Goal: To have a connect icon in the action bar. OnClick, it should try to connect in the background. While it is trying to connect, the connection animation should play. It should then switch back to "not_connected" or "connected" drawable, depending on success or failure.
Problem: If I call the code inside the onClick method of the Custom Action Provider, it works perfectly (see commented-out portion that toggles it). When the same exact code is inside onPreExecute of the AsyncTask, it will not play (it stays on the first frame), even though I am passing a reference to the ImageView.
My setup: To do a Frame Animation in the action bar, you have to use a Custom Action Provider (see animationDrawable is not playing in Actionbar?). So, I have a custom layout, a Custom Action Provider that inflates it and sets up the on-click method. My connection functionality is inside an AsyncTask so that it will connect asynchronously.
Any ideas?
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/connect"
android:showAsAction="always"
android:title="#string/btn_connect"
android:actionProviderClass="com.****.ConnectIconActionProvider"
/>
</menu>
layout/connecting_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ivConnecting"
style="#android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_not_connected" />
anim/connectinganimation.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/ic_connecting1" android:duration="300" />
<item android:drawable="#drawable/ic_connecting2" android:duration="300" />
<item android:drawable="#drawable/ic_connecting3" android:duration="300" />
</animation-list>
ConnectIconActionProvider.java
public class ConnectIconActionProvider extends ActionProvider {
private Context context;
private ImageView button;
// boolean toggle = false;
private AnimationDrawable animationDrawable;
public ConnectIconActionProvider(Context context) {
super(context);
this.context = context;
}
#Override
public View onCreateActionView(MenuItem forItem) {
// Inflate the action view to be shown on the action bar.
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.connecting_animation, null);
button = (ImageView) view.findViewById(R.id.ivConnecting);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyClass.toggleConnectionToDevice(button);
// if (toggle) {
// button.setImageResource(R.anim.connectinganimation);
// animationDrawable = (AnimationDrawable) button.getDrawable();
// animationDrawable.start();
// } else {
// button.setImageResource(R.drawable.ic_not_connected);
// if (animationDrawable != null) {
// animationDrawable.stop();
// }
// }
// toggle ^= true;
}
});
return view;
}
MyClass.toggleConnectionToDevice
public void toggleConnectionToDevice(ImageView iv) {
if (deviceConnected) {
(new DisconnectProgressBar(this, iv)).execute();
} else {
(new ConnectProgressBar(this, iv)).execute();
}
}
ConnectProgressBar.java
public class ConnectProgressBar extends AsyncTask<Void, Void, Void> {
private final MainActivity activity;
private AnimationDrawable animationDrawable;
private ImageView iv;
private Handler handler = new Handler(Looper.getMainLooper());
public ConnectProgressBar(final MainActivity activity, final ImageView iv) {
this.activity = activity;
this.iv = iv;
}
#Override
protected void onPreExecute() {
if (iv != null) {
iv.setImageResource(R.anim.connectinganimation);
animationDrawable = (AnimationDrawable) iv.getDrawable();
animationDrawable.start();
}
}
#Override
protected Void doInBackground(final Void... params) {
// Connect to Car
handler.post(new Runnable() {
public void run() {
activity.isCurrentlyConnecting = true;
activity.connect();
}
});
return null;
}
#Override
protected void onPostExecute(final Void result) {
if (activity.deviceConnected) {
// Show Connected Icon
if (animationDrawable != null) {
animationDrawable.stop();
}
if (iv != null) {
iv.setImageResource(R.drawable.ic_connected);
}
} else {
Toast.makeText(activity, "Connect failed!", Toast.LENGTH_LONG).show();
// Show Disconnected Icon
if (animationDrawable != null) {
animationDrawable.stop();
}
if (iv != null) {
iv.setImageResource(R.drawable.ic_not_connected);
}
}
}
}
I ended up scrapping the custom action provider and animation xml. I am just doing it manually with a timer inside of my AsyncTask. It might not be as "correct", but it's definitely simpler.
public class ConnectProgressBar extends AsyncTask<Void, Void, Void> {
private final MainActivity activity;
private MenuItem item;
private Timer timer;
public ConnectProgressBar(final MainActivity activity) {
this.activity = activity;
}
#Override
protected void onPreExecute() {
startAnimation();
}
#Override
protected Void doInBackground(final Void... params) {
// Connect to Car
activity.connectHardware();
return null;
}
#Override
protected void onPostExecute(final Void result) {
stopAnimation();
if (myClass.deviceConnected) {
// Show Connected Icon
if (item != null) {
setIcon(R.drawable.ic_connected);
setTitle(R.string.btn_disconnect);
}
} else {
Toast.makeText(activity, "Connect failed!", Toast.LENGTH_LONG).show();
// Show Disconnected Icon
if (item != null) {
setIcon(R.drawable.ic_not_connected);
setTitle(R.string.btn_connect);
}
}
}
private void startAnimation() {
if (timer == null) {
timer = new Timer();
}
timer.schedule(new AnimateTask(), 0, 300);
}
private class AnimateTask extends TimerTask {
int frame = 0;
AnimateTask() {
if (item == null) {
item = activity.myMenu.findItem(R.id.connect);
}
if (item != null) {
setTitle(R.string.btn_connecting);
}
}
#Override
public void run() {
// Animate!
switch (frame % 3) {
case 0:
setIcon(R.drawable.ic_connecting1);
break;
case 1:
setIcon(R.drawable.ic_connecting2);
break;
case 2:
setIcon(R.drawable.ic_connecting3);
break;
}
frame++;
}
}
private void setIcon(final int resId) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
item.setIcon(resId);
}
});
}
private void setTitle(final int resId) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
item.setTitle(resId);
}
});
}
private void stopAnimation() {
timer.cancel();
timer = null;
}
}
I figured out the issue with my initial block of code. The handler is running on the UI thread, so it blocks the UI thread from updating.
private Handler handler = new Handler(Looper.getMainLooper());
protected Void doInBackground(final Void... params) {
handler.post(new Runnable() {
public void run() {
activity.isCurrentlyConnecting = true;
activity.connect();
}
});
return null;
}
Related
I am working on a game project. I want to associate each view of my game to its respective thread and then update the view according to the logic running in that thread.
To simplify, I am posting a sample:
This is Main Activity class, which will implement the UI:
public class Main extends Activity{
private View root;
private boolean ready = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
private void init() {
setContentView(R.layout.s_main);
root = findViewById(R.id.root);
ViewTreeObserver vto = root.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
root.getViewTreeObserver().removeOnPreDrawListener(this);
ready = true;
return true;
}
});
}
public void start(View view) {
try {
if (ready && !Threads.run) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
new AsyncTasks(this, R.id.txv1).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new AsyncTasks(this, R.id.txv2).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new AsyncTasks(this, R.id.txv1).execute();
new AsyncTasks(this, R.id.txv2).execute();
}
} else {
Threads.run = false;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
This is AsyncTask extended class to update View:
public class AsyncTasks extends AsyncTask<Void, Void, String> {
private TextView view;
private boolean breakMove;
private String updateError;
public AsyncTasks(Activity activity, int viewId) {
breakMove = false;
updateError = null;
view = activity.findViewById(viewId);
}
#Override
protected String doInBackground(Void... voids) {
String message;
Threads.run = true;
try {
while (!breakMove) {
publishProgress();
Thread.sleep(100);
}
message = updateError != null ? updateError : "Thread Ends";
} catch (Exception ex) {
ex.printStackTrace();
message = ex.getMessage();
}
return message;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
try {
breakMove = !Threads.run;
if (view != null)
view.setText(String.valueOf(Math.random() * 100));
} catch (Exception ex) {
breakMove = true;
ex.printStackTrace();
updateError = ex.getMessage();
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Threads.run = false;
}
}
This works good. But there are limitations:
AsyncTask is recommended for short duration threads, not for Game or Long Running Thread projects.
In latest android frameworks, only 5 AsyncTask threads can run simultaneously and rest will be in waiting queue. So it will not work if my project requires more than 5 views to update simultaneously.
What I have tried:
Rest of other Thread implementations like Runnable, Handler, Service etc. don't allow to update views. Please keep in mind that my threads are coded in separate external files or classes.
runOnUiThread is not recommended since it runs on UI thread so it will make Main thread busy all time and also it's output is noticeable after the thread which called it, ends.
I am looking for a simple clean solution like I have coded above to implement Updation of Multiple Views through Multiple Threads.
Thanks in advance
I found a solution. Simple and clean:
public class Main extends Activity{
private View root;
private Runs runs;
private boolean ready = false;
private final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
private void init() {
setContentView(R.layout.s_main);
runs = new Runs(this);
root = findViewById(R.id.root);
//
ViewTreeObserver vto = root.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
root.getViewTreeObserver().removeOnPreDrawListener(this);
ready = true;
return true;
}
});
}
private void startRuns() {
try {
runs.run();
Threads.run = true;
} catch (Exception ex) {
Alerts.alert(context, ex.getMessage());
}
}
public void start(View view) {
try {
if (ready && !Threads.run) {
startRuns();
} else {
Threads.pause = !Threads.pause;
}
} catch (Exception ex) {
ex.printStackTrace();
Alerts.alert(context, ex.getMessage());
}
}
}
public class Runs implements Runnable {
private int count;
private Handler handler;
private TextView view1, view2;
public Runs(Activity activity) {
count = 0;
handler = new Handler();
view1 = activity.findViewById(R.id.txv1);
view2 = activity.findViewById(R.id.txv2);
}
#Override
public void run() {
if (!Threads.pause) {
update();
}
handler.postDelayed(this, Threads.sleep);
}
private void update() {
view1.setText(String.valueOf(count++));
view2.setText(String.valueOf(Math.random() * 100));
}
}
I have a recycler view. On a button click I want to remove all the items from the recyclerview but the items must be removed with animation.
I am able to remove all the items at once but I don't know how to remove them with animation. Thanks
It's old, but wish this helps someone else as it's already not answered yet; I have done it by deleting a single item at a time by simulating a swipe animation on this item, and post a delay before deleting the next item, and so on to the way down to the last item of the RecyclerView
Step No.1:
In your activity that holds the clear all button and the RecyclerView instance: Create a method of single item delete
private void deleteItem(View rowView, final int position) {
Animation anim = AnimationUtils.loadAnimation(requireContext(),
android.R.anim.slide_out_right);
anim.setDuration(300);
rowView.startAnimation(anim);
new Handler().postDelayed(new Runnable() {
public void run() {
if (myDataSource.size() == 0) {
addEmptyView(); // adding empty view instead of the RecyclerView
return;
}
myDataSource.remove(position); //Remove the current content from the array
myRVAdapter.notifyDataSetChanged(); //Refresh list
}
}, anim.getDuration());
}
Step No.2:
Create the method that will delete all RecyclerView list items >> call it in your button click callback.
boolean mStopHandler = false;
private void deleteAllItems() {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
if (myDataSource.size() == 0) {
mStopHandler = true;
}
if (!mStopHandler) {
View v = myRecyclerView.findViewHolderForAdapterPosition(0).itemView;
deleteItem(v, 0);
} else {
handler.removeCallbacksAndMessages(null);
}
handler.postDelayed(this, 250);
}
};
requireActivity().runOnUiThread(runnable);
}
Also it's important to handle configuration change in manifest, activity section, as if the configuration changes while clearing your recycler view list, an exception will be raised
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|screenSize|keyboard"
android:label="#string/app_name">
...
</activity>
This is a pretty good library and what's better is the documentation for it. You can even insert durations for transitions and animations.
Also, remember that if you are using default animation, after calling myDataSet.remove(pos) using adapter.notifyDataSetChanged() while there is an animation ongoing will cause the animation to stop.
Extend BaseItemAnimator class of recyclerview-animators library:
MyAdapter adapter = new MyAdapter(null);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setAdapter(adapter);
recyclerView.setItemAnimator(new MyScaleInLeftAnimator());
findViewById(R.id.button).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
int count = adapter.getItemCount();
adapter.clear();
adapter.notifyItemRangeRemoved(0, count);
}
}
);
...
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder{
private ArrayList<String> mItems;
...
public void clear() {
if (mItems != null) {
mItems.clear();
}
}
}
...
public class MyScaleInLeftAnimator extends BaseItemAnimator {
private long lastRemoval;
private int removeCount;
public MyScaleInLeftAnimator() {
lastRemoval = 0;
removeCount = 0;
}
public MyScaleInLeftAnimator(Interpolator interpolator) {
mInterpolator = interpolator;
lastRemoval = 0;
removeCount = 0;
}
#Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
ViewCompat.setPivotX(holder.itemView, 0);
}
#Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
long time = System.currentTimeMillis();
long d = time - lastRemoval;
if (d < 100) {
removeCount++;
} else {
removeCount = 0;
}
lastRemoval = time;
ViewCompat.animate(holder.itemView)
.scaleX(0)
.scaleY(0)
.setDuration(getRemoveDuration())
.setInterpolator(mInterpolator)
.setListener(new DefaultRemoveVpaListener(holder))
.setStartDelay(removeCount * 100)
.start();
}
#Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
ViewCompat.setPivotX(holder.itemView, 0);
ViewCompat.setScaleX(holder.itemView, 0);
ViewCompat.setScaleY(holder.itemView, 0);
}
#Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
ViewCompat.animate(holder.itemView)
.scaleX(1)
.scaleY(1)
.setDuration(getAddDuration())
.setInterpolator(mInterpolator)
.setListener(new DefaultAddVpaListener(holder))
.setStartDelay(getAddDelay(holder))
.start();
}
}
This is how I have done without using any libraries - by inserting delays in the loop to remove items & restore (if needed)
clearItemsView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final List<LineItem> lineItemsCopy = new ArrayList<>(lineItems);
new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<lineItemsCopy.size(); i++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
salesOrderItemListAdapter.removeItem(0);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
Snackbar snackbar = Snackbar.make(coordinatorLayout, getString(R.string.items_cleared_message), Snackbar.LENGTH_LONG)
.setAction(getString(R.string.label_undo), new View.OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<lineItemsCopy.size(); i++) {
final int finalI = i;
runOnUiThread(new Runnable() {
#Override
public void run() {
salesOrderItemListAdapter.restoreItem(lineItemsCopy.get(finalI), 0);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}).setActionTextColor(Color.YELLOW);
snackbar.show();
}
});
I have sample code which very simply does some heavy work and sends a message to a handler to update the UIThread. My concern is with the handler reference i am passing to the constructor. If my activity gets destroyed while the asncTask is still running will the handler reference not be null ?
public class SomeActivity extends Activity
{
private static final int UPDATE_BUTTON_TEXT = 1;
private static final SomeActivity me = null;
private static Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (me == null) return;
switch (msg.what) {
case UPDATE_BUTTON_TEXT:
Button btn = (Button) me.findViewById(R.id.someButton);
btn.setText((String) msg.obj);
}
}
};
private View.OnClickListener onClickListener = new View.OnClickListener() {
public void onClick(View view) {
new SomeLongRunningTask().execute();
}
};
private static class SomeLongRunningTask extends AsyncTask<Void, Void, Boolean> {
private Handler handler;
public SomeLongRunningTask(Handler handler) {
this.handler = handler;
}
#Override
protected Boolean doInBackground(Void... voids) {
try {
Thread.sleep(30000); // replace with some background logic
} catch (InterruptedException e) {}
return true;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
//can the handler be null here if activity is destroyed ????
Message msg = handler.obtainMessage(UPDATE_BUTTON_TEXT);
msg.obj = "success"
handler.sendMessage(msg);
}
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button someButton = (Button) findViewById(R.id.someButton);
someButton.setOnClickListener(onClickListener);
}
#Override
protected void onStart() {
super.onStart();
me = this;
}
#Override
protected void onStop() {
me = null;
super.onStop();
}
}
Yes, the reference of the handler is going to be retained in memory until it has a reference count > 0.
I think you should use AsyncTask().onProgressUpdate for updating progress on UI, which does what you're trying to do.
EDIT
If you're updating ui in onPostExecute then you don't need to use onProgressUpdate(my apologies).
Just use an interface as a callback function like below:
private interface Callback {
void updateUI(String value);
}
private static class SomeLongRunningTask extends AsyncTask<Void, String, Boolean> {
private Callback mCallback;
public SomeLongRunningTask(Callback callback) {
mCallback = callback;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
mCallback.updateUI("success");
}
}
// somewhere else...
Callback callback = new Callback() {
#Override
public void updateUI(String value) {
Button btn = (Button) me.findViewById(R.id.someButton);
btn.setText((String) msg.obj);
}
};
new SomeLongRunningTask(callback).execute();
Also it doesn't seem right to have a handler instance as a static variable. It will last until the class is unloaded.
As a rule, whenever I write an AsyncTask subclass, I use a pattern like this:
private WeakReference<Callback> mCallbackRef;
public MyAsyncTask(Callback callback) {
mCallbackRef = new WeakReference<>(callback);
}
#Override
protected void onPostExecute(Boolean aBoolean) {
if (mCallbackRef != null) {
Callback callback = mCallbackRef.get();
if (callback != null) {
callback.updateUI("success");
}
}
}
I am new in android programming.
So I have an ArrayList<String> and i want to speech in a loop and when i click a button , speech stop and if i click same button , speech start again.
My layout is something like this :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btnPauseResume"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause" />
</LinearLayout>
and my java code is like this :
public class Activity_test extends Activity {
Button btnPauseResume = null;
boolean IsPaused = false;
private TextToSpeech tts = null;
ArrayList<String> Texts = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
btnPauseResume = (Button) findViewById(R.id.btnPauseResume);
Texts = new ArrayList<String>();
btnPauseResume.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Activity_test.this.runOnUiThread(new Runnable() {
#Override
public void run() {
IsPaused = !IsPaused;
if (IsPaused) {
btnPauseResume.setText("Resume");
} else {
btnPauseResume.setText("Pause");
Start();
}
}
});
}
}).start();
}
});
Start();
}
public void Start() {
new Thread(new Runnable() {
public void run() {
Texts.clear();
Texts.add("Long Text 1");
Texts.add("Long Text 2");
Texts.add("Long Text 3");
Speech();
}
}).start();
}
public void Speech() {
tts = new TextToSpeech(Activity_test.this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
// TODO Auto-generated method stub
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.ENGLISH);
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Toast.makeText(Activity_test.this, "This Language is not supported", Toast.LENGTH_SHORT).show();
} else {
for (String Text : Texts) {
if (!IsPaused) {
tts.speak(Text, TextToSpeech.SUCCESS, null);
while (tts.isSpeaking()) {
//wait till speech finish
}
}
}
if (!IsPaused) {
Start();
}
}
} else
Toast.makeText(Activity_test.this, "Initilization Failed!", Toast.LENGTH_SHORT).show();
}
});
}
}
in real code the array list of text is changed so this is the reason i call the method Speach() to load new ArrayList to speech.
so the problem is when i click on the button it dose not work (and back button too).
Try replacing your Threads with Handlers and Runnables.
See http://developer.android.com/reference/android/os/Handler.html
I would also make sure that the code in the OnClickListener is actually invoked (using debug/log).
I have two images in my drawable folder and I desire to alternate the two images in my view every x time.
I try to use a Asynctask but don't work and I can't found the solution.
My xml Code
<ImageView
android:id="#+id/imageload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="64dp"
android:adjustViewBounds="false"
android:baselineAlignBottom="false"
android:contentDescription="#string/imatge"
android:cropToPadding="false"
android:fitsSystemWindows="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:src="#drawable/hdtitol2" />
I call the class with:
new ModifyImage().execute(null,null,null);
The main class contains de class with async code
public class ModifyImage extends AsyncTask<Void, Void, Void> {
ImageView img= (ImageView)findViewById(R.id.imageload);
#Override
protected void onPreExecute(){
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
int i = 0;
boolean opt = true;
boolean exit = false;
while(!exit){
if(i == 1000){
i = 0;
if(!opt){
img.setImageResource(R.drawable.blackhdtitol2);
opt =true;
}else{
opt = false;
img.setImageResource(R.drawable.hdtitol2);
}
}
i++;
}
return null;
}
#Override
protected void onPostExecute(Void i){
}
}
Do this,
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Integer tag = (Integer) img.getTag();
if(tag == R.drawable.blackhdtitol2){
img.setImageResource(R.drawable.blackhdtitol2);
img.setTag(R.drawable.blackhdtitol2);
}else{
img.setImageResource(R.drawable.hdtitol2);
img.setTag(R.drawable.hdtitol2);
}
}
}, 60*1000);
In the end I found a possible solution descarting all de java code that I had about this problem.
The solution that I found is to create a new class
public class RepeatingThread implements Runnable {
private final Handler mHandler = new Handler();
public RepeatingThread() {
}
#Override
public void run() {
final ImageView img = (ImageView) findViewById(R.id.imageload);
if(img.getVisibility() == View.INVISIBLE ){
img.setVisibility(View.VISIBLE);
}else{
img.setVisibility(View.INVISIBLE);
}
mHandler.postDelayed(this, 1000);
}
}
And the code in the function on create:
final Thread t = new Thread(new RepeatingThread());
t.start();