web-dev-qa-db-ja.com

別のスレッドを使用してhttpリクエストを実行する方法

ユーザーが特定のボタンをクリックしたときにHTTPリクエストを実行する(具体的にはFogBugz APIを呼び出す)アプリケーションがあります。現在、アプリケーションの起動時にサービスを作成し、そのサービスのさまざまなメソッドを呼び出してリクエストを完了しています。ただし、これを行うと、UIスレッドで通常のハングが発生します。私はAsyncTaskを見てきましたが、それが私が達成したいことを実行するかどうかはわかりません。 HTTPリクエストが返すXMLを即座に解析する必要があるため、このデータをUIスレッドに返すことができるプロセスが必要です。 ASyncTaskはこれを実行できますか、それとも他の方法がありますか?

    public static InputStream makeRequest(String httpRequest)
    {
        In a separate thread, run HTTP Request, get back and process, return inputstream
    }

このメソッドは、HttpRequestsを実行するために他のいくつかによって呼び出されます。入力ストリームが返されると、他のメソッドは特定の情報を解析します。

24
mbauer14

それを行う最も簡単な方法は、次のようなことをすることです

_//Body of your click handler
Thread thread = new Thread(new Runnable(){
  @Override
  public void run(){
    //code to do the HTTP request
  }
});
thread.start();
_

これにより、run()メソッド内のコードが新しい実行スレッドで実行されます。個人的に使用したことはありませんが、必要に応じて非同期タスクを調べることができます。これは、作業をすばやく簡単に行う方法です。

情報の返送に関しては、 Handlerオブジェクト を使用します。これにより、特定のスレッドのメッセージキューを設定し、特定のコードの実行を引き起こすメッセージをそこに渡すことができます。これを行う必要があるのは、Androidは、UIスレッド以外のスレッドが実際のUIを更新できないようにするためです。

それはあなたの質問に対処しますか?私の最初のパスはあなたの問題のすべてに完全には対処しなかったと思います。

Edit基本的には、Activityのようにハンドラーオブジェクトを定義します

_private Handler handler_ = new Handler(){
    @Override
    public void handleMessage(Message msg){

    }

};
_

ハンドラーに何をすべきかを伝えるのに役立つ静的int定数も作成します。基本的にこれらを使用して、ハンドラーの1つのインスタンスに渡されるいくつかの異なるタイプのメッセージを許可します。返されるメッセージが1つだけになる場合は、そのことを心配する必要はありません。

例えば

_private static final int UPDATE_UI = 1;
_

呼び出すハンドラーにメッセージを送信するには

_handler_.sendMessage(Message.obtain(handler_, UPDATE_UI, inputStreamInstance));
_

ハンドラーから:

_private Handler handler_ = new Handler(){
    @Override
public void handleMessage(Message msg){
    switch(msg.what){
            case UPDATE_UI:
            InputStream is = (InputStream)msg.obj;
            //do what you need to with the InputStream
            break;
        }
    }

};
_

または、inputStreamInstanceがMessageオブジェクトに追加されている場合は、任意のオブジェクトを渡すことができます。そのため、それをある種のコンテナオブジェクトなどに解析したい場合は、それを行うこともできます。ハンドラー内からそのオブジェクトにキャストし直すだけです。

74
Chris Thompson

AsyncTaskを使用してみてください。これに行く Link for more:

_private class SyncIncoData extends AsyncTask<String, String, String> {
    ProgressBar pb;
    ProgressBar pbar;

    @Override
    protected String doInBackground(String... urls) {
        for (int i = 0; i <= 100; i++) {
            publishProgress(i);
        }
        return null;
    }

    @Override
    protected void onPreExecute() {

        super.onPreExecute();

        pb = (ProgressBar) findViewById(R.id.progressBarsync4);
        pb.setVisibility(View.VISIBLE);

    }

    @Override
    protected void onPostExecute(String result) {

        pb = (ProgressBar) findViewById(R.id.progressBarsync4);
        pb.setVisibility(View.INVISIBLE);

    }

    @Override
    protected void onProgressUpdate(String... values) {
        pbar = (ProgressBar) findViewById(R.id.progressBarpbar);
        pbar.setProgress(Integer.parseInt(values[0]));
        super.onProgressUpdate(values);
    }
}
_

Httpリクエスト用のプログラムをdoinbackgroud()内に記述します

5
Jin