在 ANDROID 中使用 AsyncTask() 启动 AlertDialog 时如何避免应用程序崩溃?
How to avoid application crashing when launching AlertDialog using AsyncTask() in ANDROID?
在 Android 应用程序中,通过单击片段中的按钮,我想使用 AsynTask() 方法显示 AlertDialog。我在 onPreExecute()
中放置了调用 AlertDialog
的函数。在doInBackground()
,有一个任务运行,在onPostExecute()
,我驳回了AlertDialog
。
就在我单击按钮时发生崩溃。并且引用了LoadingDialog中的行代码class,也就是dialog.show();
。我已经尝试了网站上给出的许多建议,但是,问题再次出现。
谁能帮帮我?
这是LoadingDialog.java
public class LoadingDialog {
private Activity activity;
private AlertDialog dialog;
LoadingDialog(Activity myActivity){
activity = myActivity;
}
public void startLoadingDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
LayoutInflater inflater = activity.getLayoutInflater();
builder.setView(inflater.inflate(R.layout.custom_dialog, null));
builder.setCancelable(false);
dialog = builder.create();
dialog.show();
}
public void dismissDialog(){
dialog.dismiss();
}
}
这是我的片段class
public class MyFragment extends Fragment {
View view ;
private Button btn_;
private Activity activity;
private AlertDialog dialog;
private LoadingDialog loadingDialog;
public MyFragment(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.view = inflater.inflate(R.layout.fragment_, container, false);
loadingDialog = new LoadingDialog(getActivity());
btn_ = this.view.findViewById(R.id._button);
eventListnerReinitialiser();
return this.view;
}
public void eventListnerReinitialiser() {
this.btn_.setOnClickListener(v -> {
new ShowDialogAsyncTask().execute();
});
}
public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
int s = 0;
@Override
protected void onPreExecute() {
loadingDialog.startLoadingDialog();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
for(int i=0;i<1000000;i++)
s = s + i;
Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
return null;
}
@Override
protected void onPostExecute(Void result) {
loadingDialog.dismissDialog();
super.onPostExecute(result);
}
}
}
而且我在 Android studio
的控制台中有这个错误日志
E/WindowManager: android.view.WindowLeaked: Activity com.example.myproject.Menu2Activity has leaked window DecorView@96c506[] that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:338)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
您正在 AsyncTask 的 doInBackground()
中展示敬酒,这无法完成。 只能在主线程更新Ui
在后台线程 运行 中的 doInBackground()
中显示祝酒词 会引发异常,您的片段在那一刻被迫关闭,但是导致异常的对话框仍然打开。
所以尝试在 AsyncTask 的 onPostExecute
中调用 Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
。
下面是 AsyncTask 部分的操作方法。
public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
int s = 0;
@Override
protected void onPreExecute() {
loadingDialog.startLoadingDialog();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
for(int i=0;i<100_000_000;i++)
s = s + i;
return null;
}
@Override
protected void onPostExecute(Void result) {
Toast.makeText(MainActivity.this, "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
loadingDialog.dismissDialog();
super.onPostExecute(result);
}
}
除此之外,Vivek 还说:
- 将 ShowDialogAsyncTask 更改为静态 class
- 将对话框作为 WeakReference 传递,然后在它所在的每个地方使用 weakReference.get()
使用
- 显示对话框传递 context.getApplicationContext() 作为弱引用。
目前您的 Activity 正在通过 AsyncTask 泄漏。
在 Android 应用程序中,通过单击片段中的按钮,我想使用 AsynTask() 方法显示 AlertDialog。我在 onPreExecute()
中放置了调用 AlertDialog
的函数。在doInBackground()
,有一个任务运行,在onPostExecute()
,我驳回了AlertDialog
。
就在我单击按钮时发生崩溃。并且引用了LoadingDialog中的行代码class,也就是dialog.show();
。我已经尝试了网站上给出的许多建议,但是,问题再次出现。
谁能帮帮我?
这是LoadingDialog.java
public class LoadingDialog {
private Activity activity;
private AlertDialog dialog;
LoadingDialog(Activity myActivity){
activity = myActivity;
}
public void startLoadingDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
LayoutInflater inflater = activity.getLayoutInflater();
builder.setView(inflater.inflate(R.layout.custom_dialog, null));
builder.setCancelable(false);
dialog = builder.create();
dialog.show();
}
public void dismissDialog(){
dialog.dismiss();
}
}
这是我的片段class
public class MyFragment extends Fragment {
View view ;
private Button btn_;
private Activity activity;
private AlertDialog dialog;
private LoadingDialog loadingDialog;
public MyFragment(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.view = inflater.inflate(R.layout.fragment_, container, false);
loadingDialog = new LoadingDialog(getActivity());
btn_ = this.view.findViewById(R.id._button);
eventListnerReinitialiser();
return this.view;
}
public void eventListnerReinitialiser() {
this.btn_.setOnClickListener(v -> {
new ShowDialogAsyncTask().execute();
});
}
public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
int s = 0;
@Override
protected void onPreExecute() {
loadingDialog.startLoadingDialog();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
for(int i=0;i<1000000;i++)
s = s + i;
Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
return null;
}
@Override
protected void onPostExecute(Void result) {
loadingDialog.dismissDialog();
super.onPostExecute(result);
}
}
}
而且我在 Android studio
的控制台中有这个错误日志
E/WindowManager: android.view.WindowLeaked: Activity com.example.myproject.Menu2Activity has leaked window DecorView@96c506[] that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:338)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
您正在 AsyncTask 的 doInBackground()
中展示敬酒,这无法完成。 只能在主线程更新Ui
在后台线程 运行 中的 doInBackground()
中显示祝酒词 会引发异常,您的片段在那一刻被迫关闭,但是导致异常的对话框仍然打开。
所以尝试在 AsyncTask 的 onPostExecute
中调用 Toast.makeText(view.getContext(), "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
。
下面是 AsyncTask 部分的操作方法。
public class ShowDialogAsyncTask extends AsyncTask<Void, Void, Void> {
int s = 0;
@Override
protected void onPreExecute() {
loadingDialog.startLoadingDialog();
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
for(int i=0;i<100_000_000;i++)
s = s + i;
return null;
}
@Override
protected void onPostExecute(Void result) {
Toast.makeText(MainActivity.this, "Valeur de s = "+ s, Toast.LENGTH_LONG).show() ;
loadingDialog.dismissDialog();
super.onPostExecute(result);
}
}
除此之外,Vivek 还说:
- 将 ShowDialogAsyncTask 更改为静态 class
- 将对话框作为 WeakReference 传递,然后在它所在的每个地方使用 weakReference.get() 使用
- 显示对话框传递 context.getApplicationContext() 作为弱引用。
目前您的 Activity 正在通过 AsyncTask 泄漏。