Android非同期のいくつかの方法

10354 ワード

Android非同期処理のいくつかの方法
1,データベースuriへのクエリの非同期方式----asyncQueryHandler

まずAsyncQueryHandler継承クラスQueryHandlerを書き、次に
new mQueryHandlerオブジェクト.クエリーが完了すると、次のようにonQueryComplete関数がコールバックされます.
   
private void query() {  
      
            Uri uri = Sms.CONVESATION_URI;  
      
            mQueryHandler.startQuery(0, null, uri, CONVERSATION_PROJECTION, null, null, "sms.date desc");  
      
        }  
      
        //           
      
        private final class QueryHandler extends AsyncQueryHandler {  
      
            public QueryHandler(ContentResolver cr) {  
      
                super(cr);  
      
            }  
      
       
      
            @Override  
      
            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {  
      
                super.onQueryComplete(token, cookie, cursor);  
      
                //   mAdapter Cursor  
      
                mAdapter.changeCursor(cursor);  
      
            }  
      
        }  

2,Thread+Handlerを用いた非UIスレッド更新UIインタフェース
例は次のとおりです.

    public class ThreadHandlerActivity extends Activity {  
        /** Called when the activity is first created. */  
          
        private static final int MSG_SUCCESS = 0;//           
        private static final int MSG_FAILURE = 1;//           
          
        private ImageView mImageView;  
        private Button mButton;  
          
        private Thread mThread;  
          
        private Handler mHandler = new Handler() {  
            public void handleMessage (Message msg) {//    ui      
                switch(msg.what) {  
                case MSG_SUCCESS:  
                    mImageView.setImageBitmap((Bitmap) msg.obj);//imageview         logo  
                    Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_success), Toast.LENGTH_LONG).show();  
                    break;  
      
                case MSG_FAILURE:  
                    Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_failure), Toast.LENGTH_LONG).show();  
                    break;  
                }  
            }  
        };  
          
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
            mImageView= (ImageView) findViewById(R.id.imageView);//     ImageView  
            mButton = (Button) findViewById(R.id.button);  
            mButton.setOnClickListener(new OnClickListener() {  
                  
                @Override  
                public void onClick(View v) {  
                    if(mThread == null) {  
                        mThread = new Thread(runnable);  
                        mThread.start();//      
                    }  
                    else {  
                        Toast.makeText(getApplication(), getApplication().getString(R.string.thread_started), Toast.LENGTH_LONG).show();  
                    }  
                }  
            });  
        }  
          
        Runnable runnable = new Runnable() {  
              
            @Override  
            public void run() {//run()          
                HttpClient hc = new DefaultHttpClient();  
                HttpGet hg = new HttpGet("http://csdnimg.cn/www/images/csdnindex_logo.gif");//  csdn logo  
                final Bitmap bm;  
                try {  
                    HttpResponse hr = hc.execute(hg);  
                    bm = BitmapFactory.decodeStream(hr.getEntity().getContent());  
                } catch (Exception e) {  
                    mHandler.obtainMessage(MSG_FAILURE).sendToTarget();//        
                    return;  
                }  
                mHandler.obtainMessage(MSG_SUCCESS,bm).sendToTarget();//      , ui    MSG_SUCCESS   bitmap    
      
    //          mImageView.setImageBitmap(bm); //  !    ui    ui    
      
    //          mImageView.post(new Runnable() {//             ui     。  
    //                
    //              @Override  
    //              public void run() {//run()    ui      
    //                  mImageView.setImageBitmap(bm);  
    //              }  
    //          });  
            }  
        };  
          
    }  

3,AsyncTaskを使用したUIインタフェースの非同期更新
AsyncTaskはバックグラウンドスレッドの実行の5つの状態を抽象化し、それぞれ:1、実行の準備、2、バックグラウンドで実行中、3、進捗更新、4、バックグラウンドタスクの完了、5、タスクのキャンセル、この5つの段階について、AsyncTaskは5つのコールバック関数を提供した.
1.実行準備:タスクが実行された直後にUIスレッドによって呼び出されるonPreExecute().このステップは、通常、タスクを確立し、ユーザインタフェース(UI)に進捗バーを表示するために使用される.
2、バックグラウンドで実行中:doInBackground(Params...)、このコールバック関数は、onPreExecute()メソッドの実行が終了すると、バックグラウンドスレッドによって呼び出されます.通常、ここでは時間のかかるバックグラウンド計算が実行されます.計算結果は、この関数によって返され、onPostExecute()に渡される必要があります.この関数ではpublishProgress(Progress...)も使用できます.をクリックして、1つ以上の進捗単位(unitsof progress)をパブリッシュします.これらの値はonProgressUpdate(Progress...)になります.で、UIスレッドにパブリッシュされます.
3.進捗更新:onProgressUpdate(Progress...)、この関数はUIスレッドによってpublishProgress(Progress...)メソッド呼び出しが完了すると呼び出されます.一般に、進捗バーを動的に表示するために使用されます.
4.バックグラウンドタスクの完了:onPostExecute(Result)バックグラウンド計算が終了した後に呼び出されます.バックグラウンド計算の結果はパラメータとしてこの関数に渡されます.
5、キャンセルタスク:onCancelled()AsyncTaskのcancel()メソッドを呼び出すときに呼び出す
サンプルコード:

public class AsyncTaskActivity extends Activity {  
      
    private ImageView mImageView;  
    private Button mButton;  
    private ProgressBar mProgressBar;  
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
          
        mImageView= (ImageView) findViewById(R.id.imageView);  
        mButton = (Button) findViewById(R.id.button);  
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);  
        mButton.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                GetCSDNLogoTask task = new GetCSDNLogoTask();  
                task.execute("http://csdnimg.cn/www/images/csdnindex_logo.gif");  
            }  
        });  
    }  
      
    class GetCSDNLogoTask extends AsyncTask<String,Integer,Bitmap> {//  AsyncTask  
  
        @Override  
        protected Bitmap doInBackground(String... params) {//         ,         
            publishProgress(0);//    onProgressUpdate(Integer... progress)    
            HttpClient hc = new DefaultHttpClient();  
            publishProgress(30);  
            HttpGet hg = new HttpGet(params[0]);//  csdn logo  
            final Bitmap bm;  
            try {  
                HttpResponse hr = hc.execute(hg);  
                bm = BitmapFactory.decodeStream(hr.getEntity().getContent());  
            } catch (Exception e) {  
                  
                return null;  
            }  
            publishProgress(100);  
            //mImageView.setImageBitmap(result);          ui  
            return bm;  
        }  
          
        protected void onProgressUpdate(Integer... progress) {//   publishProgress     , ui      
            mProgressBar.setProgress(progress[0]);//          
         }  
  
         protected void onPostExecute(Bitmap result) {//            , ui      
             if(result != null) {  
                 Toast.makeText(AsyncTaskActivity.this, "      ", Toast.LENGTH_LONG).show();  
                 mImageView.setImageBitmap(result);  
             }else {  
                 Toast.makeText(AsyncTaskActivity.this, "      ", Toast.LENGTH_LONG).show();  
             }  
         }  
           
         protected void onPreExecute () {//  doInBackground(Params...)     , ui      
             mImageView.setImageBitmap(null);  
             mProgressBar.setProgress(0);//       
         }  
           
         protected void onCancelled () {// ui      
             mProgressBar.setProgress(0);//       
         }  
          
    }  
      
  
}  

次は対応するxmlです

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical" android:layout_width="fill_parent"  
    android:layout_height="fill_parent">  
    <ProgressBar android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal"></ProgressBar>  
    <Button android:id="@+id/button" android:text="    " android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>  
    <ImageView android:id="@+id/imageView" android:layout_height="wrap_content"  
        android:layout_width="wrap_content" />  
</LinearLayout> 

具体的なAsyncTaskの実現原理は参考にすることができる
http://blog.csdn.net/mylzc/article/details/6774131
またhandlerメカニズムの詳細な解析については,以下を参照する.
http://blog.csdn.net/mylzc/article/details/6771331