Android Java: метод AlertDialog, вызванный из другого класса, вызывает исключение нулевого указателя - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь вызвать метод из другого класса, который затем вызывает метод AlertDialog, и я пробовал много вещей, но это всегда вызывает исключение нулевого указателя. Вызывающий класс работает на веб-сервере, и у меня есть список 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.this, getApplicationContext(), getBaseContext() ... Я пытался сохранить контекст в onCreate как getApplicationContext() и использовать его.

Я пытался использовать решение из этого вопроса, чтобы получить контекст, но это тоже не сработало. Буду очень признателен за любую помощь.

РЕДАКТИРОВАТЬ: Забыл упомянуть, что я также пытался создать предупреждение таким образом:

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

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

Получил решение от здесь в ответ от Дэн Брей . Необходимо использовать контекст c.

Поскольку вы звоните извне действия, вам нужно сохранить контекст в классе действия:

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.

0 голосов
/ 28 февраля 2020

вы забыли создать диалог оповещения, чтобы он был пустым, а не контекст

Android простой диалог оповещения

...