Android - Create dynamically a menu after a server response - android

I would fill dynamically my menu item after a request at web server.
I have created my AsyncTask class, but when start my activity, rightly I obtain a
NullPointerException in onCreateOptionsMenu.
It's possible create the menu after that AsyncTask finishes the process?

When your AsyncTask returns the result in the onPostExecute, call your Activiy's invalidateOptionsMenu method:
http://developer.android.com/reference/android/app/Activity.html#invalidateOptionsMenu()
That will cause the onCreateOptionsMenu to be called.
The issue now is to inflate MenuItems from your AsyncTask result (and stick them into the Menu):
http://developer.android.com/reference/android/view/Menu.html

Related

How to correctly manage ASynkTaks in Tabs which have the same fragment class

I have a FragmentActivity with 7 tabs, and all of them refers to the same fragment, the only difference is a parameter, that makes them to load throught an ASyncTask the data to show from a PHP that returns a JSON. My problem is that when I swipe from one tab to another, if the task from the first tab is still loading, it loads in the new tab, or crash, or doesnt do anything. However, the activity load two tabs, so the task is launched twice and is the same problem. Any idea?
While AsyncTasks are wonderful to have, they are intended to be procedures that are independent of any UI (e.g. saving information). For the longest time I was in the same boat and used AsyncTasks for work that would end up changing the UI (since hey, they have an onPost method).
What you should be using for any work that will affect the UI is called a Loader which will pay attention to the UI state of the Fragment. In your case the AsyncTask is probably attempting to access a UI element that no longer exists (View Pagers only keep the previous, current, and next views in memory). The Loader will pay attention to this and not attempt to change the UI.
There are plenty of examples out on the web, but in short you will need to create (extend) a Loader for each of your AsyncTasks (I recommend AsyncTaskLoader, if you do pay attention to forceLoad) and add the callbacks (LoaderManager.LoaderCallbacks) to your Fragment. Then when you are ready to load call getLoaderManager().restartLoader(LOADER_ID, bundle_args, loader_callback);
Keep a reference of your AsyncTask. I assume you have a callback which let's you know when the tabs have changed. When you get notified that tabs have changed you can check if your AsyncTask is null or not finished yet, if it isn't you call it's cancel() method.
if(asyncTask!=null && asyncTask.getStatus()!=AsyncTask.Status.FINISHED) {
asyncTask.cancel(false);
asyncTask = null;
}

Android:ListView not displaying items when power button locks the screen during AsyncTask

I have a Async Task that creates a HashMap to create a Adapter to populate ListView. I have a progress dialog that shows during doInBackground method.In onPostExecute() method, I dismiss the progress dialog and call a method that populates my listview with the list of items saved in doInBackground method.
This works fine. But I noticed something strange:
The issue I see is, if I lock the screen when the progress dialog is about to be dismissed (in onPostExecute), the listview does not display, even though it has non-empty items in it. I verified it in logcat messages and when I debugged.
Is there a possibility that a screen lock (I do this my pressing power button once) blocking UI thread? How can I resolve the issue and make sure ListView displays its items?
Code for onResume():
#Override
protected void onResume(){
super.onResume();
if(MyAdapter !=null){
pull_listView.setAdapter(MyAdapter);//pull_listView is listview
MyAdapter.notifyDataSetChanged();//MyAdapter is the adapter
}
}
This situation illustrates the downside of using AsyncTask to do background processing. In some cases, an IntentService may be a better choice, especially if you think the background work is going to take some time. An AsyncTask ties the background work to the current Activity, while an IntentService is completely decoupled.
The Android training class Running in a Background Service shows you how to set up an IntentService, request work, and notify your Activity when the work is done. Passing data from the IntentService to the Activity is a bit more complicated, but there are options.
onStop() will be called when your screen goes out as per the Activity Lifecycle. You could override onStart() or onResume() and put a check in there to see if your data has been populated. If not, populate. You may even want to overide 'onStop()' to save data if the screen goes out.
Edit
In this particular situation, I would think onResume() or onStart() would be fine but onResume() is usually the safest because it is guaranteed to get called before the Activity is shown as illistrated in the link I gave. What kiind of a check you want to use is up to you and depends on how you handle evrything. However, if your AsyncTask is an inner class of your Activity class the you could simply create a boolean member variable, say boolean isDone=false; change this to true in your doInBackground() or onPostExecute() then your onResume() knows the data Is loaded. If its false then you can try to get data again. Hope this makes sense and can help

Execute an AsyncTask after Activity is shown

I'm developing an Android 3.1 application.
I want to execute an AsyncTask after activity is shown. I want to show something to user before execute AsyncTask.
I've read that it is not recommend to execute AsyncTask on onCreate().
Where I have to execute AsyncTask on onStart() or onResume()?
I want to left enough time to show activity before execute it.
onCreate(), onStart() and onResume() are lifecycle methods called by the operating system and shouldn't be called directly. You can however override them to have your code executed at these stages of the activities lifecycle:
However, if you want your AsyncTask to start after all of your Views have been inflated and drawn to the screen then you need to put the code in this:
toReturn.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
toReturn.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// asyncTask.execute();
}
});
In the above example toReturn is a view in your onCreate() method. It can be any view you like.
This pulls a ViewTreeObserver from the View and add's a listener to it which will be called when the view has finished being drawn to the screen. It's important you keep the "removeGlobalOnLayoutListener()` line in as this will stop the code firing every time the View is drawn.
Answer is in onResume()
I hade same requirement in my activity where i need to show some list with other buttons and images..
List were getting data from server so used AsyncTask for that..
But before that required to show empty listview and other part of the screen..
so first when it goes to onCreate() I set empty arraylist to listview's adapter then in onResume() call the Asynctask and in that task fill the ArrayList and call adapter.notifyDataSetChanged()
Then another problem occure..when i go to next activity and come back it always call the asynctask even if i dont require..
So had put some condition like if(arrayList.size()==0) then call asynctask else dont.
You can put yur code in the onWindowsFocusChanged method. You can use a thread inside it to manage the timer to start your specific asynctask.
Be aware that this would be performed each time your activity have the focus, not only the first time you launch your activity (I don't know if this could be a problem for you).
implement a View object and override the onDraw().
that way you'll know exactly when the first screen is visible to the user

Android: Run function after Activity is created

Currently, my app starts with a menu. Once a menu item is clicked, it starts a Activity which grabs content from an online API.
The problem I am having is, once the menu item is clicked, the application waits until the http request and response is complete before it displays the activity.
My Question is, How can I have the Activity display instantly with the layout and static View. Then once the activity is loaded, then I start fetching data from an API?
Why run after when you can run concurrently!!
Use an AsyncTask in your onCreate()/onResume() method.
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(...);
AsyncTask task = new MyTask();
task.execute(/* optional params */);
}
In your implementation of MyTask, put your long running code (the data fetched from the http request) into the doInBackground() method. Once the doInBackground() method returns, you can update your View in onPostExecute().
Also, take a look at Painless Threading, as there is lots of helpful android threading information in there.
You may use either an AsyncTask during the onCreate method to fetch your results and update your activity Asynchronously. Additionally, I think you may use a separate thread to do the same functionality. Pretty common use case. Here's the relevant Android docs.

Refresh ActionBar from an AsyncTask

I have a ListView Activity that uses a AsyncTask to load data from the database. This Activity has an options menu that checks to see if there are any data items in the Activities ListView in onPrepareOptionsMenu().
If there are items, I enable one of the options that is shown on the ActionBar that allows the user to delete the items.
Now, when the Activity starts, the AsyncTask starts and as onPrepareOptionsMenu() is run through while the AsyncTask is still running, this menu item is never enabled, unless the device is flipped and the listview data gets passed in as an instance, bypassing the AsyncTask.
So, in the AsyncTask's onPostExecute(), I call invalidateOptionsMenu() but that does not seem to be the menu to refresh (I have debugging code in onCreateOptionsMenu() and onPrepareOptionsMenu(), and neither is fired). Any help appreciated.
You can try creating a global boolean like haveData on your Activity and upon onPostExecute(), set the boolean to true or false accordingly. Then based on the boolean do a check on your onPrepareOptionsMenu() and enable the menu item accordingly.
The last time i tried it worked for me not sure why it didn't for you. Do a debug from there if it doesn't work tell us where it isn't executing.
The issue was related to a bad global variable value. I was gatewaying the code inside the onPrepareOptionsMenu() method with a global boolean value that was never true, and had put the debugging statement INSIDE the boolean check... resulting in the debugging statement never running.
After addressing that issue, everything is working as expected, code above is correct.

Categories

Resources