When we load a list, such as the GridView, we usually use Thread, Timer, or AsyncTask to avoid blocking the UI, all these operations are performed by opening another thread in the background to find data for us. The specific data obtained requires Handler to update the UI, asyncTask is also the same as the Handler used, but it encapsulates the Handler in the onPostExecute execution operation. This operation may cause a problem. For example, you have a list update database that uses AsyncTask asynchronous operations to update the UI, your need is to count the number of data in the list as soon as I come in, or set the status of a row to the selected status. The traditional method is to directly create an AsyncTask class so that it execute (); and then operate the UI. The idea is correct, but there is a problem we should note that because it is a way to load data asynchronously, and it may take some time for you to query a large amount of data, when AsyncTask is used to perform asynchronous loading and then update the UI and then operate on the UI object, a null pointer may be reported.
This problem occurs because we all know that code execution is performed from top to bottom. When you load data asynchronously, the Code allows you to perform asynchronous operations regardless of (multithreading ), the code will continue to be executed. The code below is the UI in the operation list. As you can imagine, the asynchronous loading of data is not over and your UI has not been updated yet, your list should be empty, and a null pointer will be reported when you operate on an empty list.
Analyze problems
All the students who have used AsyncTask know that the following two methods are required to load data asynchronously:
DoInBackground is executed in the background, and time-consuming operations can be put here. Note that you cannot directly operate the UI here.
OnPostExecute is equivalent to Handler's way of processing the UI. Here, you can use the result processing operation UI obtained in doInBackground.
If necessary, you have to rewrite the following three methods, but they are not required:
OnProgressUpdate allows you to use progress bars to increase user experience.
OnPreExecute this is the interface used by the end user to call the Excute
OnCancelled
According to the above ideas, we can see that the final data loading and display of this series of operations are in the onPostExecute method, so how to listen to all the UIS has been processed in onPostExecute, then we will execute what we want to do?
Solve the problem
Here are my own ideas for solving this problem. If you have any better ideas, please share them with us.
First create an interface
Private interface isLoadDataListener {
Public void loadComplete ();
}
Declare this interface variable
Private isLoadDataListener loadLisneter;
Assign a value to the interface to obtain the interface object.
Public void setLoadDataComplete (isLoadDataListener dataComplete ){
This. loadLisneter = dataComplete;
}
Then, call this interface after the onPostExecute of AsyncTask finishes processing the UI. The following is an AsyncTask class used by my previous project:
Class loadGridAsyncTask extends AsyncTask <Integer, Integer, using adapter> {
Private int poindex;
Public loadGridAsyncTask (int positionindex ){
This. poindex = positionindex;
}
@ Override
Protected expose adapter doInBackground (Integer... params ){
// TODO Auto-generated method stub
// MAppsModel. clear ();
Cursor temp = dbHelper. queryPageById (poindex );
LoadPage (mApps, temp );
Temp. close ();
Return new callback adapter (STB. this, mAppsModel );
}
@ Override
Protected void onPostExecute (invalid adapter result ){
GridViewExt itemGrid = (gridViewExt) viewFlipper
. GetChildAt (poindex );
ItemGrid. setColumnCount (pageColumnCount );
ItemGrid. setAdapter (result );
If (loadLisneter! = Null ){
LoadLisneter. loadComplete ();
}
}
}
Through the above Code, we get an interface returned after data loading is complete. The next problem is that we use this interface to process our UI, for example, let a UI be selected, to obtain the number of UIS in this list, see the following code:
New loadgridasynctask(1cmd.exe cute ();
SetLoadDataComplete (new isLoadDataListener (){
@ Override
Public void loadComplete (){
// TODO Auto-generated method stub
// Perform the operation here. The code above will be called automatically after the UI update is complete}
});
This article is intended to help Android Developers who have been getting started.