AsyncTask и контексты

Итак, я разрабатываю свое первое многопоточное приложение, использующее Android с классом AsyncTask. Я пытаюсь использовать его, чтобы отключить геокодер во втором потоке, а затем обновить пользовательский интерфейс с помощью onPostExecute, но я все время сталкиваюсь с проблемой с соответствующим контекстом.

Я как-то ковылял свой путь с помощью Contexts в основном потоке, но я не совсем уверен, что такое Контекст или как его использовать в фоновом потоке, и я не нашел на нем хороших примеров. Любая помощь? Вот отрывок из того, что я пытаюсь сделать:

public class GeoCode extends AsyncTask<geothread, void,="" geothread=""> {
 @Override
 protected GeoThread doInBackground(GeoThread... i) {
 List</geothread,><address><code> addresses = null;
 Geocoder geoCode = null; 
 geoCode = new Geocoder(null); //Expects at minimum Geocoder(Context context);
 addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1);
 }
}
</code>
<p>Он продолжает терпеть неудачу на шестой строке из-за неправильного контекста.</p></address>
5 ответов

@Юджин ван дер Мерве

Для меня работает следующий фрагмент кода:) →

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


Контекст - это объект, который обеспечивает accees для среды выполнения приложения. В большинстве случаев, когда вам нужно получать объекты из среды Android, такие как ресурсы, представления, классы инфраструктуры и т.д., Вам нужно иметь Контекст в ваших руках.

Чтобы получить экземпляр Context очень просто, когда вы находитесь в классе Activity - сама деятельность является подклассом контекста, поэтому все, что вам нужно сделать, - это использовать ключевое слово 'this' для указания вашего текущего контекста,

Создайте код, который может потребовать Контекст - вы должны позаботиться о передаче объекта контекста из своей родительской активности. В случае вашего примера вы можете добавить явный конструктор, который принимает Контекст как входной аргумент.


Я сделал еще несколько исследований, и кто-то предложил передать его в поток (не знаю, почему я об этом не думал). Я передал его в поток Geocoder через аргумент, и так оно и было.


Проблема с обновлением пользовательского интерфейса из AsyncTask заключается в том, что вам нужен текущий контекст активности. Но контекст уничтожается и воссоздается для каждого изменения ориентации.

Вот хороший ответ на ваш вопрос: поведение контекста Android AsyncTask


Если не похоже, что вы используете параметры. Вы можете использовать это для передачи в Conetxt.

public class GeoCode extends AsyncTask<context, void,="" geothread=""> {
 @Override
 protected GeoThread doInBackground(Context... params) {
 List</context,><address><code> addresses = null;
 Geocoder geoCode = null; 
 geoCode = new Geocoder(params[0]); //Expects at minimum Geocoder(Context context);
 addresses = geoCode.getFromLocation(GoldenHour.lat, GoldenHour.lng, 1);
 }
}
</code>
<p>Затем изнутри вашей деятельности:</p>
<pre class="prettyprint linenums">GeoCode myGeoCode = new GeoCode();
myGeoCode.execute(this);

licensed under cc by-sa 3.0 with attribution.