简体   繁体   English

为什么调用 dialog.show() 会导致错误?

[英]Why is calling dialog.show() causing an error?

In activity, I run alertdialog and an error occurs in my application.在活动中,我运行 alertdialog 并在我的应用程序中发生错误。 After which the application closes.之后应用程序关闭。 In this forum I found a similar problem.在这个论坛我发现了一个类似的问题。 Advised to add the onDestroy() method: Activity has leaked window that was originally added建议添加 onDestroy() 方法: Activity hasleaked window 原来添加的

I added, but probably wrong, because I am only learning and do not understand much.我补充了,但可能是错误的,因为我只是在学习,并不太了解。 onDestroy() is lit in red. onDestroy() 以红色点亮。 How can I write the code correctly?如何正确编写代码?

import

public class ActivityBox_4 extends AppCompatActivity {

SharedPreferences sp;

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

    sp = getSharedPreferences("app_data", 0);

    SharedPreferences sp = getSharedPreferences("app_data",0);

    TextView Moltext27 = findViewById(R.id.Moltext27);
    String text27 ="<br />" + "<b>\t\t\tМОЛИТВА ДО СВЯТОГО (СВЯТОЇ)</b><br />"+
            "\t\t\tДо тебе, о святий угодниче Божий/ <i>свята угоднице Божа (ім’я), <br />";
    Moltext27.setTextSize(TypedValue.COMPLEX_UNIT_SP,sp.getInt("size",18));
    Moltext27.setText(Html.fromHtml(text27));

    TextView Moltext28 = findViewById(R.id.Moltext28);
    String text28 = "<b>\t\t\tМОЛИТВА ЗА ТИХ, КОГО ПЕРЕСЛІДУЮТЬ ЗА ВІРУ ПРАВОСЛАВНУ</b><br />"+
            "\t\t\tСпаси, Господи, і помилуй старців і молодих, нужденних і сиріт і тих, <br />";
    Moltext28.setTextSize(TypedValue.COMPLEX_UNIT_SP,sp.getInt("size",18));
    Moltext28.setText(Html.fromHtml(text28));


    final ScrollView scrollView = findViewById(R.id.scroll_2);

    Button move_27 = findViewById(R.id.butM_27);
    Button move_28 = findViewById(R.id.butM_28);


    move_27.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            scrollView.postDelayed(new Runnable() {
                public void run() {
                    scrollView.scrollTo(0, (int) findViewById(R.id.Moltext27).getY());
                }
            }, 100);
        }
    });

    move_28.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            scrollView.postDelayed(new Runnable() {
                public void run() {
                    scrollView.scrollTo(0, (int) findViewById(R.id.Moltext28).getY());
                }
            }, 100);
        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_HOME) {

        return true;
    }

    return super.onKeyDown(keyCode, event);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.Сhoose_Size) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("Оберіть розмір тексту");
        final String[] sizes = {"16", "18", "20", "22", "24", "26"};

        int selected_item = -1;

        switch (sp.getInt("size", -1)) {
            case 16:
                selected_item = 0;
                break;
            case 18:
                selected_item = 1;
                break;
            case 20:
                selected_item = 2;
                break;
            case 22:
                selected_item = 3;
                break;
            case 24:
                selected_item = 4;
                break;
            case 26:
                selected_item = 5;
                break;
        }

        builder.setSingleChoiceItems(sizes, selected_item, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int item) {

                switch (item) {
                    case 0:
                        sp.edit().putInt("size", 16).apply();
                        recreate();
                        break;
                    case 1:
                        sp.edit().putInt("size", 18).apply();
                        recreate();
                        break;
                    case 2:
                        sp.edit().putInt("size", 20).apply();
                        recreate();
                        break;
                    case 3:
                        sp.edit().putInt("size", 22).apply();
                        recreate();
                        break;
                    case 4:
                        sp.edit().putInt("size", 24).apply();
                        recreate();
                        break;
                    case 5:
                        sp.edit().putInt("size", 26).apply();
                        recreate();
                        break;
                }

            }


        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
protected void onDestroy()
{
    super.onDestroy();
    if (dialog!=null && dialog.isShowing()){
        dialog.dismiss();
    }
}

}

2019-08-12 13:45:03.966 15878-15878/ua.pl.prayerbook E/WindowManager: android.view.WindowLeaked: Activity ua.pl.prayerbook.old_unused.ActivityBox_4 has leaked window DecorView@b946dac[] that was originally added here
    at android.view.ViewRootImpl.<init>(ViewRootImpl.java:417)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
    at android.app.Dialog.show(Dialog.java:316)
    at ua.pl.prayerbook.old_unused.ActivityBox_4.onOptionsItemSelected(ActivityBox_4.java:171)
    at android.app.Activity.onMenuItemSelected(Activity.java:3204)
    at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:436)
    at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:196)
    at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
    at android.support.v7.app.AppCompatDelegateImpl.onMenuItemSelected(AppCompatDelegateImpl.java:888)
    at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840)
    at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
    at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
    at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:128)
    at android.widget.AdapterView.performItemClick(AdapterView.java:310)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1155)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3120)
    at android.widget.AbsListView.onTouchUp(AbsListView.java:4047)
    at android.widget.AbsListView.onTouchEvent(AbsListView.java:3806)
    at android.support.v7.widget.DropDownListView.onTouchEvent(DropDownListView.java:217)
    at android.support.v7.widget.MenuPopupWindow$MenuDropDownListView.onTouchEvent(MenuPopupWindow.java:129)
    at android.view.View.dispatchTouchEvent(View.java:9943)   
 at android.view.ViewGroup.dispatchTransformedTouchEvent 
(ViewGroup.java:2663)

Check this out for Dialog Creation.查看此对话框创建。

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Оберіть розмір тексту");
final String[] sizes = {"16", "18", "20", "22", "24", "26"};

int selected_item = -1;

switch (sp.getInt("size", -1)) {
    case 16:
        selected_item = 0;
        break;
    case 18:
        selected_item = 1;
        break;
    case 20:
        selected_item = 2;
        break;
    case 22:
        selected_item = 3;
        break;
    case 24:
        selected_item = 4;
        break;
    case 26:
        selected_item = 5;
        break;
}

builder.setSingleChoiceItems(sizes, selected_item, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int item) {

        switch (item) {
            case 0:
                sp.edit().putInt("size", 16).apply();
                recreate();
                break;
            case 1:
                sp.edit().putInt("size", 18).apply();
                recreate();
                break;
            case 2:
                sp.edit().putInt("size", 20).apply();
                recreate();
                break;
            case 3:
                sp.edit().putInt("size", 22).apply();
                recreate();
                break;
            case 4:
                sp.edit().putInt("size", 24).apply();
                recreate();
                break;
            case 5:
                sp.edit().putInt("size", 26).apply();
                recreate();
                break;
        }

    }


});

builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }
});


builder.show();

Please define AlertDialog.Builder builder = new AlertDialog.Builder(this);请定义 AlertDialog.Builder builder = new AlertDialog.Builder(this); globally and try在全球范围内尝试

Like this : -像这样 : -

    public class ActivityBox_4 extends AppCompatActivity {

    SharedPreferences sp;
    AlertDialog.Builder builder;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_box_4);
     builder = new AlertDialog.Builder(this);
}

Looks like you want to show some dialog to choose a font size, but you are doing it from onOptionsItem selected.看起来你想显示一些对话框来选择字体大小,但你是从 onOptionsItem 选择的。 To solve it you need:要解决它,您需要:

  • Create the class level variable of a dialog, which you'll be able to dismiss;创建对话框的类级别变量,您可以将其关闭;
  • Move dialog creation to a separate method;将对话框创建移至单独的方法;
  • Create this dialog from activity, not from the menu.从活动创建此对话框,而不是从菜单。

I'm not sure why are you doing it from the menu, but I guess you need to send some event to the activity and then build the dialog.我不确定您为什么要从菜单中执行此操作,但我想您需要向活动发送一些事件,然后构建对话框。

Example:例子:

private AlertDialog mDialog;

public AlertDialog.Builder createDialog() {
    AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);

    builder.setTitle(R.string.CONTACTDETAIL__status_offline)
            .setMessage(R.string.CONNECTION_BANNER__text)
            .setPositiveButton(R.string.GENERIC__ok, (dialog, which) -> mPresenter.connectionDialogClosed());
    builder.setCancelable(false);
    return builder;
}
  • Dismiss it in onStop();在 onStop() 中关闭它;
  • To show it, just call show() on return from this method object;要显示它,只需在从此方法对象返回时调用 show() 即可;

Despite that, you will lose your dialog on rotate, try to read about the ViewModels and LiveData to solve it.尽管如此,您将在旋转时丢失对话框,请尝试阅读有关 ViewModels 和 LiveData 的信息来解决它。 https://developer.android.com/topic/libraries/architecture/viewmodel https://developer.android.com/topic/libraries/architecture/viewmodel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM