web-dev-qa-db-ja.com

AsyncTaskとコンテキスト

そのため、AsyncTaskクラスでAndroidを使用して、最初のマルチスレッドアプリケーションを作成しています。これを使用して、2番目のスレッドでGeocoderを起動し、UIを次のように更新しようとしています。 onPostExecuteですが、適切なコンテキストで問題が発生し続けます。

メインスレッドでコンテキストを使用する方法を少し迷いましたが、コンテキストが何であるか、またはバックグラウンドスレッドでどのように使用するかが正確にわからず、良い例が見つかりませんでした。何か助けはありますか?これが私がやろうとしていることの抜粋です:

public class GeoCode extends AsyncTask<GeoThread, Void, GeoThread> {
  @Override
  protected GeoThread doInBackground(GeoThread... i) {
    List<Address> addresses = null;
    Geocoder geoCode = null; 
    geoCode = new Geocoder(null); //Expects at minimum Geocoder(Context context);
    addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1);
  }
}

不適切なコンテキストが原因で、6行目で失敗し続けます。

19
Michael

@Eugene van der Merwe

次のコードは私にとってはうまくいきます:)->

public class ApplicationLauncher extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.applicationlauncher);

    LoadApplication loadApplication = new LoadApplication(this);
    loadApplication.execute(null);
}

private class LoadApplication extends AsyncTask {

    Context context;
    ProgressDialog waitSpinner;
    ConfigurationContainer configuration = ConfigurationContainer.getInstance();

    public LoadApplication(Context context) {
        this.context = context;
        waitSpinner = new ProgressDialog(this.context);
    }

    @Override
    protected Object doInBackground(Object... args) {
        publishProgress(null);
        //Parsing some stuff - not relevant
        configuration.initialize(context);
        return null;
    }

    @Override
    protected void onProgressUpdate(Object... values) {
        super.onProgressUpdate(values);
        // Only purpose of this method is to show our wait spinner, we dont
        // (and can't) show detailed progress updates
        waitSpinner = ProgressDialog.show(context, "Please Wait ...", "Initializing the application ...", true);
    }

    @Override
    protected void onPostExecute(Object result) {
        super.onPostExecute(result);
        waitSpinner.cancel();
    }
}
}

乾杯、

Ready4Android

18
Ready4Android

コンテキストは、アプリケーションのランタイム環境へのアクセスを提供するオブジェクトです。ほとんどの場合、リソース、ビュー、インフラストラクチャクラスなど、Android環境からオブジェクトを取得する必要がある場合は、コンテキストを手に入れる必要があります。

Activityクラスにいる場合、Contextインスタンスを取得するのは非常に簡単です(Activity自体はContextのサブクラスであるため、必要なのは 'this'キーワードを使用して現在のコンテキストを指すことだけです。

Contextを必要とする可能性のあるコードを作成する場合は常に、親アクティビティからContextオブジェクトを渡すように注意する必要があります。あなたの例の場合、入力引数としてContextを受け入れる明示的なコンストラクターを追加できます。

4
Vladimir Kroz

私はさらに調査を行い、誰かがそれをスレッドに渡すことを提案しました(なぜ私がそれを考えなかったのかわかりません)。引数を介してGeocoderスレッドに渡しましたが、そのように機能しました。

2
Michael

AsyncTaskからUIを更新する際の問題は、currentアクティビティコンテキストが必要なことです。ただし、向きが変わるたびにコンテキストが破棄されて再作成されます。

これがあなたの質問に対する良い答えです: Android AsyncTaskコンテキストの振る舞い

1
espinchi

Paramsを使用しているように見えない場合。これを使用して、Conetxtを渡すことができます。

public class GeoCode extends AsyncTask<Context, Void, GeoThread> {
  @Override
  protected GeoThread doInBackground(Context... params) {
    List<Address> addresses = null;
    Geocoder geoCode = null; 
    geoCode = new Geocoder(params[0]); //Expects at minimum Geocoder(Context context);
    addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1);
  }
}

次に、アクティビティ内から:

GeoCode myGeoCode = new GeoCode();
myGeoCode.execute(this);
0