スレッドメソッドAndroid:非同期呼び出しの詳細

7532 ワード

PS:今日の午前中、とても憂鬱で、簡単な基礎の問題がたくさんあって、私は少し迷って、ああ、コードは何日も書かないで忘れました.今のところCOOではないので、コードを覚えなければなりません.
実際のアプリケーションでは、ネットワーク接続、データベース操作など、時間のかかるタスクの処理が頻繁に行われますが、これらの操作がメインスレッド(UIスレッド)に置かれていると、UIの偽死の光景が形成され、AndroidではAsyncTaskとHandlerの2つの非同期方式を適用してこのような問題を解決することができます.
    AsyncTask:
Androidが提供する軽量級の非同期クラスは、AsyncTaskを直接継承し、クラスで非同期動作を実現し、現在の非同期実行のレベル(インタフェースによるUI進捗更新が可能)をインタフェースにフィードバックし、最後に実行結果をUIメインスレッドにフィードバックすることができる.応用の長所:簡単、迅速、プロセス制御応用の欠点:複数の非同期操作を応用し、UIの変革を行う必要がある時、複雑になる.
AsyncTaskを適用する場合、処理クラスはAsyncTaskを継承し、3つの汎用パラメータを提供し、AsyncTaskを再ロードする4つの方法(少なくとも1つ)を必要とする.
3つの汎用パラメータ:1.Paramタスクアクチュエータに必要なデータ型2.Progressバックグラウンド計算で適用する進捗単位データ型3.Resultバックグラウンド計算で結果を返すデータ型は、パラメータを設定するときに通常、String...params、これは方法が0つ以上のこのタイプのパラメータを有することができることを示す.パラメータを適用しないように設定できる場合があります.Voidで...いいですよ.
4つの方法:1.onPreExecute()は、UIスレッドで実行される前処理を実行し、進捗バーコントロールの描画など、バックグラウンドタスクの準備を行うことができます.2.doInBackground(Params...)バックグラウンドプロセスが実行する具体的な計算はここで実現され、doInBackground(Params...)AsyncTaskの問題点で、この方法は再ロードする必要があります.この方法ではpublishProgress(Progress...)を適用できる.現在の進捗値を変更します.3.onProgressUpdate(Progress...)UIスレッドで実行します.doInBackground(Params...)ででpublishProgress(Progress...)を適用し、この方法がトリガーされます.ここでは、進捗バーコントロールに対して進捗値に応じて具体的な応答を行うことができます.4.onPostExecute(Result)はUIスレッドで実行され、バックグラウンドタスクの結果を処理することができ、結果はdoInBackground(Params...)である.で行ないます.このメソッドは、Resultがnullの場合、バックグラウンド・タスクが完了していない(キャンセルまたは例外が発生した)ことを示す場合にも頻繁に再ロードされます.
非同期タスククラスコード:
    
// AsyncTask        

class DownImageTask extends AsyncTask<String, Integer, Bitmap> {

	//      

	@Override

	protected void onPreExecute() {

		super.onPreExecute();

		//      

		progressBar.setVisibility(View.VISIBLE);

		progressBar.setMax(100);

	}

	//        

	@Override

	protected Bitmap doInBackground(String... params) {

		try {

			URL url = new URL(params[0]);

			HttpURLConnection conn = (HttpURLConnection) url

					.openConnection();

			InputStream inputStream = conn.getInputStream();

			bitmap = BitmapFactory.decodeStream(inputStream);

			//       ,             ,                             

			for (int i = 1; i <= 10; i++) {

				publishProgress(i * 10);

				Thread.sleep(200);

			}

			inputStream.close();

		} catch (Exception e) {

			e.printStackTrace();

		}

		return bitmap;

	}

	//    UI  ,            ,doInBackground               

	@Override

	protected void onPostExecute(Bitmap result) {

		super.onPostExecute(result);

		ImageView imageView = (ImageView) findViewById(R.id.image);

		imageView.setImageBitmap(result);

		progressBar.setVisibility(View.GONE);

	}

	//    UI  ,   doInBackground(Params...)    publishProgress(Progress...),       

	@Override

	protected void onProgressUpdate(Integer... values) {

		super.onProgressUpdate(values);

		progressBar.setProgress(values[0]);

	}

}

毎日同じ理屈
たとえ青春は1本のあでやかな花ですとしても、しかし私は知っていて、1本の独放は永遠に春ではありませんて、春は万紫千紅の世界です.青春は大地の雄大な岸の木であっても、私は知っていて、1株の独秀は永遠にまっすぐではありませんて、列をなす林木を作って、風を遮って砂を遮る緑の万里の長城です.青春は一葉の海の孤高の帆であっても、一葉の孤帆は遠航しにくく、千帆が競い合うのが海の壮観であることは知っている.
呼び出しコード:
public class MainActivity extends Activity {  

    private Button button;

    private ProgressBar progressBar; 

      

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.main);  

          

        button = (Button)findViewById(R.id.button);

        progressBar = (ProgressBar)findViewById(R.id.progressBar);

          

        button.setOnClickListener(new OnClickListener() {  

              

            @Override  

            public void onClick(View v) {  

                ProgressBarAsyncTask asyncTask = new DownImageTask();  

                asyncTask.execute("http://www.baidu.com/img/baidu_jgylogo3.gif");

            }  

        });

    }

    
    Handler:
    
HandlerはMessageオブジェクトとRunnableオブジェクトをプライマリスレッドに配布できます.各Handlerインスタンスは、作成したスレッドに都市バインドされます(一般的にはプライマリスレッドにあります).
2つの役割:
メッセージのレイアウトまたはRunnableは、プライマリ・スレッドのどこかで実行されます.
動作を異なるスレッドで実行するように配置します
Handlerフラット配信メッセージの方法:post(Runnable)postAtTime(Runnable,long)postDelayed(Runnable,long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message,long)sendMessageDelayed(Message,long)*以上のpostスイープの方法がメインスレッドで呼び出されます.*以上のsendスイープのメソッドは、他のスレッドで呼び出されます.
サンプルコード:
public class HandlerTestActivity extends Activity {



    private Button start;



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        // TODO Auto-generated method stub 

        super.onCreate(savedInstanceState);

        setContentView(R.layout.handlertest);

        start = (Button) findViewById(R.id.start);

        start.setOnClickListener(new startListener());



        System.out.println("Activity Thread:" + Thread.currentThread().getId());

    }



    Handler  handler = new Handler(){



        @Override

        public void handleMessage(Message msg) {

            // TODO Auto-generated method stub

            if (msg.what == 1) {

                //  ,     

            } else {

                //  ,..

            }

        }

        

    };

    Runnable thread  = new Runnable() {



                         @Override

                         public void run() {

                             // TODO Auto-generated method stub 

                             System.out.println("HandlerThread:" + Thread.currentThread().getId());

                             //Message message = new Message();

                             //message.what = 1;

                             //handler.sendMessage(message);



                         }

                     };



    class startListener implements OnClickListener {



        @Override

        public void onClick(View v) {

            // TODO Auto-generated method stub 

            handler.post(thread);

            //Thread t = new Thread(thread);

            //t.start();

        }

    }



}

このプログラムはHandlerの非同期メカニズムを実現したように見えますpost(thread)は新しいスレッド起動の役割を果たしたようだが、我々の発明を実行することによって、2つのスレッドのIDは同じである!つまり、現実的にはthreadが本来のメインスレッドであることから、handler.post()メソッドは実際にスレッドを新規作成するのではなく,元のスレッド上で実行するだけであり,非同期メカニズムを実現していない.startListenerを次のコードに書き換えると非同期化が可能になります.
    
class startListener implements OnClickListener {



        @Override

        public void onClick(View v) {

            // TODO Auto-generated method stub 

            //handler.post(thread);

            Thread t = new Thread(thread);

            t.start();

        }

    }

新しく作成するスレッドにrunnableを入れて実行することにより、非同期呼び出しが実現する、呼び出し完了後にマスタースレッドを通知または変更する必要がある場合は、Runnableクラスのrunメソッドでhandlerを呼び出す必要がある.sendMessage(message)
    
@Override

 public void run() {

     // TODO Auto-generated method stub 

     System.out.println("HandlerThread:" + Thread.currentThread().getId());

     Message message = new Message();

     message.what = 1;

     handler.sendMessage(message);

}

文章は终わってみんなに次のプログラマーのいくつかのジョークの语录を分かち合います:人の脳とコンピュータの同じ点と异なる点、人の脳は数字を覚えて、コンピュータも数字を覚えます;人の脳はプログラムを記憶することができて、コンピュータもプログラムを記憶することができて、しかし人の脳は感知能力を持って、このような能力のコンピュータは模倣することができなくて、人の記憶は人がどんなことをすることに影響して、しかしコンピュータはプログラムのソフトウェアだけあります.ビル氏はまた、人間の脳とコンピュータの間で最も重要な違いは潜在意識だと述べた.人間の脳が記憶を格納する特別な点について、ビル氏は、人間の脳は大きくないが、人間の脳の重要な機能は連絡であり、人間の脳は同じ記憶を異なる場所に格納するため、記憶の読み取り速度は異なるが、この速度は使用頻度と認識の重要性に依存すると述べた.人間の脳の記憶記憶記憶能力は年齢とともに退化し、同時に記憶の質も年齢とともに退化する.経典語録網