0

I'm trying to call a method from another class which then calls an AlertDialog method, and I've tried many things but it always causes a null pointer exception. The calling class is running a web server, and I have a RecyclerView list on the activity class containing the method being called. here's some code from the activity class with 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;
    }

...

}

And here's the code from my web server class:

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

It always causes null pointer exception on this line:

new AlertDialog.Builder(ListClass.this)

and where the method is called in ListClass:

showNullFieldNotification();

Error message:

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)

If I call showNullFieldNotification() in ListClass onCreate() or from the options menu it works no problem, but when called from the WebSvr class it always causes the exception.

For context on the AlertDialog I've tried ListClass.this, getApplicationContext(), getBaseContext()... I've tried to save a context in onCreate as getApplicationContext() and use that.

I've tried to use the solution from this question to get context but that didn't work either. Would really appreciate any help.

EDIT: Forgot to mention that I had also tried to build the alert in this way:

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();
    }
wdbwdb1
  • 195
  • 2
  • 9
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – itwasntme Feb 28 '20 at 03:23
  • I actually read that answer yesterday, after reading it I tried using the method which I have updated at the end of my question to see if it would add some needed initialization but it didn't help. Other than that I can’t think of a way it provides a solution to my particular problem aside from what I've already tried. Do you have a specific suggestion? – wdbwdb1 Feb 28 '20 at 04:20

2 Answers2

0

you forgot create Alert Dialog so it null, not the context

Android simple alert dialog

  • I've tried to use the solution from this answer to get context but that didn't work either\ I've actually already tried that, I updated the question with the method I used. And the method used which does not use .create() works fine when called from the same class so I don't believe it makes any difference. – wdbwdb1 Feb 28 '20 at 04:09
0

Got the solution from here in answer from Dan Bray. Needed to use a static context.

Since you are calling from outside of an activity, you'll need to save the context in activity class:

public static Context context;

And inside onCreate:

context = this;

To show notification:

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

            }
        });

The methods called in the activity class must also be public static.

wdbwdb1
  • 195
  • 2
  • 9