[Android Java:从另一个类调用AlertDialog的方法调用会导致空指针异常

问题描述 投票:0回答:2

我试图从另一个类中调用一个方法,然后再调用一个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)

如果我在showNullFieldNotification() ListClass中或从选项菜单中调用onCreate(),则它没有问题,但是从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
2个回答
0
投票

您忘记创建警报对话框,因此它为null,而不是上下文

Android simple alert dialog


0
投票

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();

            }
        });

活动类中调用的方法也必须为public static

© www.soinside.com 2019 - 2024. All rights reserved.