43

JSON 経由でサーバーとのネットワーク通信を処理するために IntentService を使用しています。JSON/サーバー部分は正常に動作していますが、必要な場所に結果を戻すのに問題があります。次のコードは、onClick() 内からインテント サービスを開始し、サービスがグローバル変数を更新して結果をメイン アクティビティに中継する方法を示しています。

public class GXActivity extends Activity {

    private static final String TAG = "GXActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // === called when the activity is first created

        Log.i(TAG, "GXActivity Created");

        super.onCreate(savedInstanceState);
        setContentView(R.layout.start);

        View.OnClickListener handler = new View.OnClickListener() {
            public void onClick(View v) {

                // === set up an application context to hold a global variable
                // === called user, to contain results from the intent service
                GXApp appState = ((GXApp) getApplicationContext());
                User user = new User(-1); // initialize user id to -1
                appState.setUser(user);

                // === next start an intent service to get JSON from the server;
                // === this service updates the user global variable with
                // === results from the JSON transaction
                Intent intent = new Intent(this, GXIntentService.class);
                startService(intent);

                // === check app context for results from intent service
                appState = ((GXApp) getApplicationContext());
                if (appState.getUser().getId() != -1)...

            }
        }
    }
}

私が抱えている問題は、JSON を解析するインテント サービスが onCreate() が完了するまで呼び出されないため、結果を探しているコードが初期化されていない結果を見てスタックすることです。

結果を確認する前にインテント サービスが呼び出されるようにするには、どうすればよいですか? onCreate() 関数からクリック リスナーを取り出したら機能しますか? このコードを構造化するための別の/より良いものはありますか? どうもありがとう。

4

4 に答える 4

86

ResultReceiverアクティビティで独自のサブクラスを作成することを検討する必要があります。ResultReceiverを実装しているので、 のエクストラとしてyour からyour にParcelable渡すことができます。ActivityServiceIntent

次のようにする必要があります。

  1. ResultReceiverアクティビティ クラス内にのサブクラスを実装します。実装する重要な方法はonReceiveResult(). このメソッドは、Bundle取得する情報を渡すために使用できる一連の結果データを提供しますService。必要なデータを解凍し、それを使用してアクティビティを更新するだけです。

  2. アクティビティで、カスタムの新しいインスタンスを作成し、それをサービスの開始に使用ResultReceiverする に追加しIntentます。

  3. Serviceのメソッドで、渡された をonStartCommand()取得し、ローカル メンバー変数に格納します。ResultReceiverIntent

  4. Service作業が完了したらsend()、 ResultReceiver を呼び出して、 でアクティビティに送り返したいデータを渡しますBundle

これは非常に効果的なパターンであり、厄介な静的変数にデータを格納していないことを意味します。

于 2012-04-26T14:11:12.090 に答える
12

バックグラウンドで結果を取得する方法はたくさんあります (AsyncTask、アクティビティをサービスにバインドする...) が、IntentService のコードを維持したい場合は、次のように簡単にできます。

1- IntentService の作業の最後に、ブロードキャスト インテント (拡張データにステータスを含む) を送信します。

2- Intent からのデータを消費する Activity に LocalBroadcastReceiver を実装する

これは、公式ドキュメントでも推奨される方法です (IntentService を維持したい場合)。

https://developer.android.com/training/run-background-service/report-status.html

于 2014-03-20T15:07:04.843 に答える
7

UI スレッドをロックせずにサーバーから JSON を取得するだけでよい場合は、AsyncTaskを使用する方が簡単な場合があります。

于 2012-04-26T14:18:09.013 に答える