【问题标题】:Android Java: AlertDialog method called from another class causes null pointer exceptionAndroid Java:从另一个类调用的AlertDialog方法导致空指针异常
【发布时间】:2020-06-12 03:17:27
【问题描述】:

我试图从另一个类调用一个方法,然后调用一个AlertDialog 方法,我尝试了很多方法,但它总是导致空指针异常。调用类正在运行一个 Web 服务器,我在包含被调用方法的活动类上有一个 RecyclerView 列表。这是来自AlertDialog的活动类的一些代码:

public class ListClass extends AppCompatActivity {

    private WebSvr server;
    private static final int PORT = 8080;
    private androidx.appcompat.widget.Toolbar toolbar;
    private ListView lv;
    private CustomAdapter customAdapter;
    public ArrayList<EditModel> editModelArrayList;
    public static String[] newList = new String[20];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_server_screen);
        toolbar = (androidx.appcompat.widget.Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        startWebServer();

        customAdapter = new CustomAdapter(this, editModelArrayList);
        lv.setAdapter(customAdapter);
    }

    public static boolean listUpdated;

    public void updateList() {
        listUpdated = false;
        Runnable r = new Runnable() {
            @Override
            public void run() {

                for (int i = 0; i < 20; i++) {
                    if (CustomAdapter.editModelArrayList.get(i).getEditTextValue() != "") {
                        newList[i] = CustomAdapter.editModelArrayList.get(i).getEditTextValue();
                    } else {
                        if (!showNotification) {

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    showNullFieldNotification(); // <------------- CALLING THIS 
                                }
                            });
                            showNotification = true;
                        }
                    }
                }
                listUpdated = true;
            }
        };
        Thread thread = new Thread(r);
        thread.start();
    }

    boolean showNotification = false;

    public void showNullFieldNotification() {
        new AlertDialog.Builder(ListClass.this)
                .setTitle("Warning, some fields are empty")
                .setNegativeButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.cancel();
                        showNotification = false;
                    }
                }).show();
    }

    public static boolean returnListUpdated() {
        return listUpdated;
    }

...

}

这是我的网络服务器类的代码:

public class WebSvr extends NanoHTTPD {

    public ListClass ListClass = new ListClass();

    public WebSvr(int port){
        super(port);
    }

    @Override
    public Response serve(String uri, Method method,
                          Map<String, String> header,
                          Map<String, String> parameters,
                          Map<String, String> files) {


        ListClass.updateList(); // <--------------- THE METHOD CALLED

        while (!ListClass.returnListUpdated()) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        String strResponse = Arrays.toString(ListClass.returnString());

        return newFixedLengthResponse(strResponse);
    }
}

这行总是导致空指针异常:

new AlertDialog.Builder(ListClass.this)

以及在ListClass中调用该方法的位置:

showNullFieldNotification();

错误信息:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.espressif.iot_esptouch_demo, PID: 18217
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
        at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:152)
        at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
        at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:224)
        at android.app.AlertDialog$Builder.<init>(AlertDialog.java:454)
        at com.myProject.ListClass.showNullFieldNotification(ListClass.java:177)
        at com.myProject.ListClass$4.run(ListClass.java:193)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6665)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:772)

如果我在 ListClass onCreate() 或从选项菜单中调用 showNullFieldNotification() ,它没有问题,但是当从 WebSvr 类调用时,它总是会导致异常。

对于AlertDialog 的上下文,我尝试过ListClass.thisgetApplicationContext()getBaseContext()... 我尝试将onCreate 中的上下文保存为getApplicationContext() 并使用它。

我尝试使用来自this 问题的解决方案来获取上下文,但这也不起作用。非常感谢任何帮助。

编辑:忘了提到我也尝试过以这种方式构建警报:

public void showNullFieldNotification2() {
        AlertDialog.Builder alert = new AlertDialog.Builder(ListClass.this);
                alert.setTitle("Warning, some fields detected as being empty or having \"0\" as value");
                alert.setNegativeButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.cancel();
                        showNotification = false;
                    }
                });
                AlertDialog dialog = alert.create();
                dialog.show();
    }

【问题讨论】:

  • 我昨天实际上阅读了该答案,阅读后我尝试使用我在问题末尾更新的方法,看看它是否会添加一些需要的初始化,但它没有帮助。除此之外,除了我已经尝试过的方法之外,我想不出一种方法来解决我的特定问题。您有什么具体建议吗?

标签: java android nullpointerexception android-alertdialog


【解决方案1】:

您忘记创建警报对话框,所以它为空,而不是上下文

Android simple alert dialog

【讨论】:

  • 我尝试使用此答案中的解决方案来获取上下文,但这也不起作用\我实际上已经尝试过,我用我使用的方法更新了问题。从同一个类调用时,不使用 .create() 的方法工作正常,所以我不相信它有任何区别。
【解决方案2】:

here 得到解决方案,来自Dan Bray 的回答。需要使用静态上下文。

由于您是从活动外部调用的,因此您需要将上下文保存在活动类中:

public static Context context;

在 onCreate 内部:

context = this;

显示通知:

new Handler(Looper.getMainLooper()).post(new Runnable(){
            @Override
            public void run(){

                new AlertDialog.Builder(context)
                        .setTitle("Warning, some fields are empty")
                        .setNegativeButton("OK",new DialogInterface.OnClickListener(){
                            @Override
                            public void onClick(DialogInterface dialogInterface,int i){
                                dialogInterface.cancel();
                                showNotification=false;
                            }
                        }).show();

            }
        });

activity类中调用的方法也必须是public static

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多