Java 异步任务和上下文
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1912725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AsyncTask and Contexts
提问by Michael
So I'm working out my first multi-threaded application using Android with the AsyncTask class. I'm trying to use it to fire off a Geocoder in a second thread, then update the UI with onPostExecute, but I keep running into an issue with the proper Context.
所以我正在使用带有 AsyncTask 类的 Android 开发我的第一个多线程应用程序。我正在尝试使用它在第二个线程中触发地理编码器,然后使用 onPostExecute 更新 UI,但我一直遇到正确上下文的问题。
I kind of hobbled my way through using Contexts on the main thread, but I'm not exactly sure what the Context is or how to use it on background threads, and I haven't found any good examples on it. Any help? Here is an excerpt of what I'm trying to do:
我在主线程上使用 Contexts 时有点蹒跚,但我不确定 Context 是什么或如何在后台线程上使用它,而且我还没有找到任何好的例子。有什么帮助吗?这是我正在尝试做的事情的摘录:
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);
}
}
It keeps failing at the sixth line there, because of the improper Context.
由于上下文不正确,它在第六行一直失败。
回答by Michael
I did some more research, and someone suggested passing it to the thread (not sure why I didn't think of that). I passed it to the Geocoder thread through an argument, and just like that, it worked.
我做了更多的研究,有人建议将它传递给线程(不知道为什么我没有想到这一点)。我通过一个参数将它传递给 Geocoder 线程,就这样,它起作用了。
回答by Vladimir Kroz
The Context is an object which provides accees to application runtime environment. In most cases when you need to obtain objects from Android environment, such as resources, views, infrastructure classes etc -- you need to have Context in your hands.
Context 是一个对象,它为应用程序运行时环境提供访问权限。在大多数情况下,当您需要从 Android 环境中获取对象,例如资源、视图、基础设施类等时——您需要掌握 Context。
To obtain Context instance is very simple when you're in the Activity class -- Activity itself is a subclass of the Context, so all you need to do -- is to use 'this' keyword to point on your current context.
当您在 Activity 类中时,获取 Context 实例非常简单——Activity 本身是 Context 的子类,因此您需要做的就是使用“this”关键字来指向当前的上下文。
Whever you create code which might require Context - you should take care to pass Context object from your parent Activity. In case of your example you could add explicit constructor which accepts Context as input argument.
无论您创建可能需要 Context 的代码 - 您都应该注意从父 Activity 传递 Context 对象。在您的示例中,您可以添加接受 Context 作为输入参数的显式构造函数。
回答by espinchi
The problem with updating the UI from an AsyncTask is that you need the currentactivity context. But the context is destroyed and recreated for every orientation change.
从 AsyncTask 更新 UI 的问题在于您需要当前的活动上下文。但是每次方向变化都会破坏并重新创建上下文。
Here's a good answer to your question: Android AsyncTask context behavior
这是您问题的一个很好的答案:Android AsyncTask 上下文行为
回答by Ready4Android
@Eugene van der Merwe
@Eugene van der Merwe
The following piece of code works for me : ) -->
以下代码对我有用:)-->
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();
}
}
}
Cheers,
干杯,
Ready4Android
Ready4Android
回答by Michael Peterson
If doesn't look like you are using the params. You could use that to pass in the Conetxt.
如果看起来不像你在使用参数。您可以使用它来传递 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);
}
}
Then from within your activity:
然后从您的活动中:
GeoCode myGeoCode = new GeoCode();
myGeoCode.execute(this);