Android: 在 AsyncTask 中吐司
Android: toast inside AsyncTask
我有一个从 Activity QuizMap
调用的 AsyncTask class SearchForQuestions
。在 SearchForQuestions
中循环遍历数组时,我无法在 AsynTask 中找到正确的 toast 上下文。
标准Toast.makeText(getApplicationContext(), "This is Toast!!!", Toast.LENGTH_SHORT).show();
给出错误getApplicationContext()
未定义。
我已经尝试了 SO 提供的一些解决方案,其中大部分都已列出 here 并且关注在其上获取 UiThread 和 运行。
但是我无法让它工作。这是我尝试过的示例代码片段。我在 QuizMap
中放置了一个方法并尝试从 SearchForQuestions
调用它,但无法识别 SearchForQuestions
。我该如何解决这个问题? )还是java的新手...)
// QuizMap activity
public class QuizMap extends FragmentActivity
implements OnMarkerClickListener {
private GoogleMap map;
private static final String TAG = "QuizMap"; // debugging
...
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quizmap);
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
...
}
// make toast inside AsyncTask
public void showNotNearToast(final String toast) {
QuizMap.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(QuizMap.this, "This is Toast!!!", Toast.LENGTH_SHORT).show();
}});
}
.
// SearchForQuestions class
private class SearchForQuestions extends AsyncTask<String, Void, DataHandler> {
// checks for proximity to question locations
Location location =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
@Override
protected DataHandler doInBackground(String... pointsList) {
String result = pointsList[0];
...
}
@Override
protected void onPostExecute(DataHandler result) {
ArrayList<String> resultsArray = result.results;
Integer numPoints = resultsArray.size();
for (int i =0;i<numPoints;i++){
String[] pointDetails = resultsArray.get(i).split("::");
...
// we can make use of the Android distanceTo function to calculate the distances
float distance = location.distanceTo(fixedLoc);
if (i > DIST) { // this is UCL
showNotNearToast("My Message"); // showNotNearToast undefined
if (distance < DIST) {
...
}
};
将 activity 传递给 AsyncTask
。见下文。
private class SearchForQuestions extends AsyncTask<String, Void, DataHandler> {
Activity activity;
public void SearchForQuestions(Activity activity){
this.activity = activity;
}
//... rest of the code
public class QuizMap extends FragmentActivity implements OnMarkerClickListener {
/*...*/
new SearchForQuestions(this).execute();
/*...*/
/*When calling the toast:*/
Toast.makeText(this.activity, "This is Toast!!!", Toast.LENGTH_SHORT).show();
Just Toast it,为什么要为它创建一个函数? onPostExecute() 已经在 UI 线程上。
您无法访问,因为内部 Class 无法调用外部 class 的函数,除非您传递外部 class.
的实例
- 在
onPostExecute
中祝酒
- 创建回调接口。
public interface ToastCallback {
public void invoke(String text);
}
你的 AsyncTask 构造器
private ToastCallback toastCallback;
public SearchQuestions(ToastCallback callback) {
this.toastCallback = callback;
}
// in doInBackground() {
toastCallback.invoke("Toast from background");
}
在你的Activity,
private void showNotNearToast(String text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
});
}
public class MyToastCallback implements ToastCallback {
@Override
public void invoke(String text) {
showNotNearToast(text);
}
}
// Asynctask call
new SearchQuestion(new MyTosatCallback()).execute(<Your params here>);
在你的 AsyncTask 中试试这个:
myActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
你在哪里
showNotNearToast("My Message"); // showNotNearToast undefined
将 myActivity
替换为您的 Activity。
(Ab)使用 publishProgress 方法
private class ToastAsyncTask extends AsyncTask<Void, String, Void>{
@Override
protected Void doInBackground(Void... voids) {
SystemClock.sleep(1000);
publishProgress("Toast msg string");
SystemClock.sleep(1000);
return null;
}
@Override
protected void onProgressUpdate(String... values) {
Toast.makeText(getApplicationContext(), values[0], Toast.LENGTH_SHORT).show();
}
}
**更新:**由于您出于某种原因遇到上下文问题,请使用此版本。艰难的上述实施对我有用。
private class ToastAsyncTask extends AsyncTask<Void, String, Void> {
private WeakReference<Context> contextRef;
public ToastAsyncTask(Context context) {
contextRef = new WeakReference<Context>(context);
}
@Override
protected Void doInBackground(Void... voids) {
SystemClock.sleep(1000);
publishProgress("Toast msg string");
SystemClock.sleep(1000);
return null;
}
@Override
protected void onProgressUpdate(String... values) {
if (contextRef.get() != null) {
Toast.makeText(contextRef.get(), values[0], Toast.LENGTH_SHORT).show();
} else {
// The context was destroyed.. check what you are doing
}
}
}
这样使用
new ToastAsyncTask(MainActivity.this).execute();
我不会结束这个问题。我还没有解决我的问题,但是在其他情况下显然有效的答案数量表明还有其他事情正在发生。我将重新构造 类 以避开必须从 AsyncTask 中调用的问题。
我有一个从 Activity QuizMap
调用的 AsyncTask class SearchForQuestions
。在 SearchForQuestions
中循环遍历数组时,我无法在 AsynTask 中找到正确的 toast 上下文。
标准Toast.makeText(getApplicationContext(), "This is Toast!!!", Toast.LENGTH_SHORT).show();
给出错误getApplicationContext()
未定义。
我已经尝试了 SO 提供的一些解决方案,其中大部分都已列出 here 并且关注在其上获取 UiThread 和 运行。
但是我无法让它工作。这是我尝试过的示例代码片段。我在 QuizMap
中放置了一个方法并尝试从 SearchForQuestions
调用它,但无法识别 SearchForQuestions
。我该如何解决这个问题? )还是java的新手...)
// QuizMap activity
public class QuizMap extends FragmentActivity
implements OnMarkerClickListener {
private GoogleMap map;
private static final String TAG = "QuizMap"; // debugging
...
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quizmap);
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
...
}
// make toast inside AsyncTask
public void showNotNearToast(final String toast) {
QuizMap.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(QuizMap.this, "This is Toast!!!", Toast.LENGTH_SHORT).show();
}});
}
.
// SearchForQuestions class
private class SearchForQuestions extends AsyncTask<String, Void, DataHandler> {
// checks for proximity to question locations
Location location =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
@Override
protected DataHandler doInBackground(String... pointsList) {
String result = pointsList[0];
...
}
@Override
protected void onPostExecute(DataHandler result) {
ArrayList<String> resultsArray = result.results;
Integer numPoints = resultsArray.size();
for (int i =0;i<numPoints;i++){
String[] pointDetails = resultsArray.get(i).split("::");
...
// we can make use of the Android distanceTo function to calculate the distances
float distance = location.distanceTo(fixedLoc);
if (i > DIST) { // this is UCL
showNotNearToast("My Message"); // showNotNearToast undefined
if (distance < DIST) {
...
}
};
将 activity 传递给 AsyncTask
。见下文。
private class SearchForQuestions extends AsyncTask<String, Void, DataHandler> {
Activity activity;
public void SearchForQuestions(Activity activity){
this.activity = activity;
}
//... rest of the code
public class QuizMap extends FragmentActivity implements OnMarkerClickListener {
/*...*/
new SearchForQuestions(this).execute();
/*...*/
/*When calling the toast:*/
Toast.makeText(this.activity, "This is Toast!!!", Toast.LENGTH_SHORT).show();
Just Toast it,为什么要为它创建一个函数? onPostExecute() 已经在 UI 线程上。
您无法访问,因为内部 Class 无法调用外部 class 的函数,除非您传递外部 class.
的实例- 在
onPostExecute
中祝酒
- 创建回调接口。
public interface ToastCallback {
public void invoke(String text);
}
你的 AsyncTask 构造器
private ToastCallback toastCallback;
public SearchQuestions(ToastCallback callback) {
this.toastCallback = callback;
}
// in doInBackground() {
toastCallback.invoke("Toast from background");
}
在你的Activity,
private void showNotNearToast(String text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
});
}
public class MyToastCallback implements ToastCallback {
@Override
public void invoke(String text) {
showNotNearToast(text);
}
}
// Asynctask call
new SearchQuestion(new MyTosatCallback()).execute(<Your params here>);
在你的 AsyncTask 中试试这个:
myActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
你在哪里
showNotNearToast("My Message"); // showNotNearToast undefined
将 myActivity
替换为您的 Activity。
(Ab)使用 publishProgress 方法
private class ToastAsyncTask extends AsyncTask<Void, String, Void>{
@Override
protected Void doInBackground(Void... voids) {
SystemClock.sleep(1000);
publishProgress("Toast msg string");
SystemClock.sleep(1000);
return null;
}
@Override
protected void onProgressUpdate(String... values) {
Toast.makeText(getApplicationContext(), values[0], Toast.LENGTH_SHORT).show();
}
}
**更新:**由于您出于某种原因遇到上下文问题,请使用此版本。艰难的上述实施对我有用。
private class ToastAsyncTask extends AsyncTask<Void, String, Void> {
private WeakReference<Context> contextRef;
public ToastAsyncTask(Context context) {
contextRef = new WeakReference<Context>(context);
}
@Override
protected Void doInBackground(Void... voids) {
SystemClock.sleep(1000);
publishProgress("Toast msg string");
SystemClock.sleep(1000);
return null;
}
@Override
protected void onProgressUpdate(String... values) {
if (contextRef.get() != null) {
Toast.makeText(contextRef.get(), values[0], Toast.LENGTH_SHORT).show();
} else {
// The context was destroyed.. check what you are doing
}
}
}
这样使用
new ToastAsyncTask(MainActivity.this).execute();
我不会结束这个问题。我还没有解决我的问题,但是在其他情况下显然有效的答案数量表明还有其他事情正在发生。我将重新构造 类 以避开必须从 AsyncTask 中调用的问题。