Change color with delay - java

I want to change the background color of a textview when I press a button. It should do this: first be white for 10ms, and then just the regular color. Is there some kind of delay function or do I need to write my own function for this using a loop or some kind? Any tip is greatly appreciated :)
At this moment I just use
button.setBackgroundColor(Color.parseColor("#ffa500"));

every view have post and postDelayed methods to respectively post a runnable to the UI thread or post delayed it.
button.postDelayed(new Runnable() {
#Override
public void run() {
// change color in here
}
}, 10);
edit:
if you're going to be calling this very often, you can do it even better with something like this:
int currentColor;
private Runnable changeColorRunnable = new Runnable() {
#Override
public void run() {
switch(currentColor){
case Color.RED: currentColor = Color.BLACK; break;
case Color.BLACK: currentColor = Color.RED; break;
}
button.setBackgroundColor(currentColor);
}
};
and then:
button.postDelayed(changeColorRunnable, 10);
this will avoid unnecessary object creation and garbage collection

The easiest way to do that would be to create an handler and to execute it with postDelayed :
http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long)

private class ButtonColorChange extends AsyncTask<String, Void, String>
{
protected void onPreExecute()
{
//do
}
protected String doInBackground(String... params)
{
try
{
Thread.sleep(10000); //waiting here
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result)
{
button.setBackgroundColor(Color.parseColor("#ffa500"));
}
}
use this method whenever you click on button as
ButtonColorChange btc = new ButtonColorChange();
btc.execute();

Related

How can I stop asynctask in android when back button is pressed?

I am running an AsyncTask and it is taking a little time to load. In that period of time, if I am pressing back button then it does not respond. It responds only after a few seconds. So how can I kill or pause or override AsyncTask to go back? Or is there any other way to do something similar?
if (mainContent != null) {
mainContent.post(new Runnable() {
#Override
public void run() {
Bitmap bmp = Utilities.getBitmapFromView(mainContent);
BlurFilter blurFilter = new BlurFilter();
Bitmap blurredBitmap = blurFilter.fastblur(bmp,1,65);
asyncTask = new ConvertViews(blurredBitmap);
asyncTask.execute();
}
});
My AsyncTask:
class ConvertViews extends AsyncTask<Void,Void,Void> {
private Bitmap bmp;
public ConvertViews(Bitmap bmp){
this.bmp = bmp;
}
#Override
protected Void doInBackground(Void... params) {
try {
//Thread.sleep(200);
if(mainViewDrawable == null) {
mainViewDrawable = new BitmapDrawable(getResources(), bmp);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
My onBackPressed():
public void onBackPressed() {
super.onBackPressed();
asyncTask.cancel(true);
finish();
}
there is no way that you can stop a asynch task instantly.Every AsynchTask has a boolean flag property associated with it so if cancel_flag =True mean task has been canceled and there is a cancel() function which can be called on aasynchtask object like this
loginTask.cancel(true);
but all this cancel() function does is ,it will set a cancel boolean(flag ) property of asynch task to True so , you can check this property with isCancelled() function inside doInBackGround and do something ,like
protected Object doInBackground(Object... x) {
while (/* condition */) {
// work...
if (isCancelled()) break;
}
return null;
}
and if it is True then you can use break the loops(if you are doing a long task) or return to go quickly out of doInBackground and calling cancel() on asynchtask will skip the execution of onPostExecute().
and the other option is ,if you want to stop multiple running asynch task in background then calling cancel on each one can be tedious so in this case you can have a boolean flag in container class(of asynchtask) and skip the working inside asynchtask if the flag has been set to True ,like
protected Object doInBackground(Object... x) {
while (/* condition */) {
// work...
if (container_asynch_running_flag) break;
}
return null;
}
but make sure to also put a check in onpostExecute in this case because it won't stop the execution of onpost.
You can stop it instantly calling asyncTask.cancel(true).
But it is not recommended to do because it can lead to memory leaks. Better to call asyncTask.cancel(false) and exit from doInBackground function manually checking isCancelled() value as #Pavneet advised.

How to update UI from background thread in a fragment

I have an app that has a Fragment with a ListView. I ping IP addresses on the network and when I get a response I add the IP address to a list. Once I've finished pinging the IP addresses, I put this list of IP addresses that replied to my ping into a ListView.
What I want to do is update this ListView as I'm pinging rather than doing after I've pinged all the IP addresses. To ping the IP addresses I'm using an AsyncTask which then calls a Runnable Thread. How do I tell the Fragment to update the UI from that Runnable class when I find an IP address?
The rough layout of my classes is below.
public class FinderFragment extends ListFragment {
private void CallFind(){
new Find().execute();
}
private class Find extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
SearchNetwork searchNetwork = new SearchNetwork(ipAddress);
try {
searchNetwork.StartFind();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
UpdateDeviceList();
}
}
}
public class SearchNetwork {
public void StartFind() throws InterruptedException {
Thread t[] = new Thread[20];
for(int i=0; i<02; i++){
t[i] = new Thread(new FindDevices(i*5));
t[i].start();
}
for(Thread thread : t){
thread.join();
}
}
class FindDevices implements Runnable{
#Override
public void run() {
//Ping the IP addresses here
//I want to update UI from here
}
}
Try this....
getActivity().runOnUiThread(new Runnable(){
#Override
public void run(){
// Do whatever you want
}
});
use Handler, runOnUiThread or View.post
android.os.Handler handler = new android.os.Handler();
handler.post(new Runnable() {
#Override
public void run() {
//update here
}
});
You should use AsyncTask instead of raw threads! There is a method onPostExecute() which runs on the main UI thread and that's the point where you can update your UI ...
But you have to keep in mind, that you have to cancel the AsyncTask (threads as well) if the fragment gets destroyed, otherwise your task will continue to run and will try to change the UI of the fragment, but the fragment doesn't exist anymore which will lead to exceptions like IllegalStateException: Fragment not attached to Activity or View Not Attached Exceptions
We can use Handler, runOnUiThread, postDelayed and AsyncTask.
AsyncTask is good option other than rest as it extends the handler class.
When you have to code in thread use the doInBackground() method like this:
class myAsyncTask extends AsyncTask(Void,Void,Void){
public doInBackground(){
// do your code here
}
}
And call it on the UI thread like this:
new MyAsyncTask().execute();
if you want to auto update every x sec you can use this:
Runnable runnable = new Runnable() {
#Override
public void run() {
while(refreshing){
handler.post(new Runnable() {
#Override
public void run() {
//do your stuff here
}
});
try{
Thread.sleep(30000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
Try
publishProgress()
and catch it in the overidden method
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}

Android Individual AsyncTask

I am having a slight problem in Android Async Task. In my MainActivity, I am calling GetEventAsyncTask which will execute the method inside called retrieveEventJSON:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = this;
public void onSingleTap(float x, float y) {
final Point point = mMapView.toMapPoint(x, y);
eventModel.setEventX(String.valueOf(point.getX()));
eventModel.setEventY(String.valueOf(point.getY()));
new MyAsyncTask(new MyAsyncTask.OnRoutineFinished() {
public void onFinish() {
CreateEvent.createEventDialog(context, point.getX(),
point.getY(), eventAddress); //this will be called after the task finishes
}
}).execute(eventModel);
}
});
new GetEventAsyncTask().execute();
}
In my GetEventAsyncTask, basically I am just retrieving the data returned from JSON and save them into an array:
public class GetEventAsyncTask extends AsyncTask<Event, Integer, Double> {
EventController eventCtrl = new EventController();
String eventAddress;
Event eventModel = new Event();
public interface OnRoutineFinished{ //interface
void onFinish();
}
private OnRoutineFinished mCallbacks;
public GetEventAsyncTask(OnRoutineFinished callback){ //constructor with interface
mCallbacks = callback;
}
public GetEventAsyncTask(){} //empty constructor to maintain compatibility
#Override
protected Double doInBackground(Event... params) {
try {
eventAddress = eventCtrl.getStreetAddressFromGeometry(eventModel.getEventX(), eventModel.getEventY());
eventCtrl.retrieveEventJSON();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Double result) {
if(mCallbacks !=null)
mCallbacks.onFinish(); //call interface on finish
}
protected void onProgressUpdate(Integer... progress) {
}
}
Then when the navigation drawer item onselected, I am calling the plotting marker on map method which takes in the array I saved just now:
case 0:
eventCtrl.plotEventOnMap(context);
break;
I tried to print out the data retrieved in retrieveJSON and it did printed out. But somehow, when I tried to plot onto the map, it does not shows anything. I wonder which part that I overlapped or reinitialize some Object?
The strange thing is if I put getEventAsyncTask under MainActivity, it did run and retrieved the data. But however, if I shifted the getEventAsyncTask out as an individual class, it stopped working. I wonder why is it so?
Thanks in advance.

Show ProgressDialog during a network call until it's FINISHED

I am very frustrated as I've been trying to implement a super simple loading wheel while waiting on a network call. I have searched and read dozens of SO questions and I just feel like I must be missing something, unless nobody really does what I'm trying to do. I have tried going down the AsyncTask route, but that's not what I want.
Let me also say that right now my app works perfectly, it's just that the transition from screen to screen appears to hang as it waits on the network. I just want a loading wheel so that in the 1-2 seconds the user knows the app is working and didn't freeze.
Here's what my current network call looks like:
private static String sendDataToServer(String arg1, String arg2)
{
Thread dbThread = new Thread()
{
public void run()
{
// do the call that takes a long time
}
};
dbThread.start();
try {
// I do this so that my program doesn't continue until
// the network call is done and I have received the information
// I need to render my next screen
dbThread.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Now, why can't I just add the ProgressDialog like this? If I do this, the progressDialog never appears.
private static String sendDataToServer(String arg1, String arg2)
{
final ProgressDialog progress = new ProgressDialog(BaseActivity.getInstance());
progress.setIndeterminate(true);
progress.setMessage("Loading...");
progress.show();
Thread dbThread = new Thread()
{
public void run()
{
// do the call that takes a long time
}
};
dbThread.start();
try {
dbThread.join();
progress.dismiss();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
I think I'm stuck because the network call needs to be on a separate thread from the UI thread, yet I don't want to continue in my application because I need the results of that call to continue. But if I do thread.join() I hold up everything. I thought I needed AsyncTask but that went downhill quickly. Here's my question on that if you're curious.
Android's AsyncTask: multiple params, returning values, waiting
How the heck to I just show a loading dialog while this call happens without proceeding through the rest of my application?
EDIT
Here's my AsyncTask attempt.
private class PostToFile extends AsyncTask<PostToFile, Void, Void>{
private String functionName;
private ArrayList<NameValuePair> postKeyValuePairs;
private String result = "";
public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
functionName= function;
postKeyValuePairs = keyValuePairs;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
}
#Override
protected Void doInBackground(PostToFile... params) {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName));
for (int i = 0; i < postKeyValuePairs.size(); i++) {
nameValuePairs.add(postKeyValuePairs.get(i));
}
try{
// ***do the POST magic.***
result = response.toString();
}
catch (Exception e){
// clean up my mess
}
return null;
}
private String getResult(){
return result; // can I use this somehow???
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
And when I use it:
new PostToPHP(FUNCTION_NAME, postPairings){
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try
{
if (result != null && !result.startsWith("null"))
{
JSONArray jArray = new JSONArray(result);
parseData(jArray);
}
}
catch (JSONException e)
{
Log.e(Constants.LOG_TAG, e.toString());
}
};
}.execute()
The problem is, I have a couple of these calls back to back, and they're each dependent on each other. So the first one starts, and the second one starts immediately after the first one starts, but before the first one is finished. So I get erroneous behavior. How can I start the second call only after the first is completely done?
Maybe this will work, I haven't tested, but you can try:
public class MyTask extends AsyncTask<String, Void, String> {
private int flag;
public MyTask(int flag) {
this.flag = flag;
}
#Override
protected String doInBackground(String... params) {
switch (flag) {
case 1:
return doNetworking1();
break;
case 2:
return doNetworking2();
break;
case 3:
return doNetworking3();
break;
default:
return doNetworking1();
}
}
#Override
protected void onPreExecute() {
//show progress dialog
}
#Override
protected void onPostExecute(String s) {
//hide progress dialog
switch (flag) {
case 1: //do something with result
new MyTask(2).execute();
break;
case 2: //do other stuff
new MyTask(3).execute();
break;
case 3: //do event more stuff
break;
default:
//do something
}
}
}
and usage:
new MyTask(1).execute();
In cases of network connections I would use IntentService instead of AsyncTask.
For example create IntentServices for network connection:
public class NetworkCallIntentService extends IntentService {
public static final String BROADCAST_ACTION = "com.yourpackage:NETWORK_CALL_BROADCAST";
public static final String RESULT = "com.yourpackage:NETWORK_CALL_RESULT";
public NetworkCallIntentService() {
super(NetworkCallIntentService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
// get data from intent if needed
// do the call that takes long time
// send broadcast when done
Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(RESULT, "some_result");//and more results
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Next, start that service from activity, show progress dialog and move code responsible for showing next screen to BroadcastReceiver#onReceive() method:
public class SomeActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//start service
Intent serviceIntent = new Intent(this, NetworkCallIntentService.class);
//put extras into intent if needed
//serviceIntent.putExtra("some_key", "some_string_value");
startService(serviceIntent);
//here just show progress bar/progress dialog
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mNetworkCallReceiver,
new IntentFilter(NetworkCallIntentService.BROADCAST_ACTION));
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mNetworkCallReceiver);
}
private BroadcastReceiver mNetworkCallReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//hide progress bar/progress dialog
//here get results from intent extras
String result = intent.getStringExtra(NetworkCallIntentService.RESULT);
//process results and continue program(go to next screen, show error message etc.)
}
}
}
Declare service in manifest file:
<service
android:name="com.yourpackage.DownloadSvtValuesIntentService"
android:exported="false" >
</service>

Can I restrict a ViewFlipper from flipping until an AsyncTask has been performed?

My application has a ViewFlipper with 3 ViewGroups in it. Each ViewGroup interaction is dependent on data from a database. I'm using an AsyncTask to read from a database and return a Cursor when it's done. Before the AsyncTask is executed, I just want to display a single View in the ViewFlipper saying "Loading data, please wait.", is this possible somehow?
Show the progress dialog in your onPreExecute() and dismiss it in the onPostExecute(). Something like this,
private class MyAsyncTask extends AsyncTask<Integer, Integer, Integer[]> {
private ProgressDialog myWait = null;
// This is on the UI thread itself
protected void onPreExecute() {
myWait = new ProgressDialog(MainActivity.this);
myWait.setMessage("Loading data, please wait");
myWait.setCancelable(false);
myWait.show();
}
// Separate worker thread is used here
protected Integer[] doInBackground(Integer...params) {
//do the database loading
return <your result - goes to onPostExecute>;
}
// This is on the UI thread itself
protected void onPostExecute(Integer[] resultCell) {
if (myWait != null) {
myWait.dismiss();
}
}
}
yes you can make use of progressDialog. Do it like this,
progressDiaolg=ProgressDialog.show(Activity.this,"","Loading Images...");
final Thread t= new Thread(new Runnable() {
public void run() {
Log.i("Inside Thread", "Downloading Images...");
downloadImages();
handler.sendEmptyMessage(0);
}
});
t.start();
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
try {
progressDiaolg.dismiss();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
};
I don't have idea with Asynctask. So try modifying this snippet accordingly.

Categories

Resources