Android Java: 从另一个 class 调用的 AlertDialog 方法导致空指针异常
Android Java: AlertDialog method called from another class causes null pointer exception
我试图从另一个 class 调用一个方法,然后调用一个 AlertDialog
方法,我已经尝试了很多方法,但它总是导致空指针异常。调用 class 是 运行 一个 Web 服务器,我在 activity class 上有一个 RecyclerView
列表,其中包含被调用的方法。这是来自 activity class 和 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;
}
...
}
这是来自我的网络服务器的代码 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);
}
}
总是在这一行引起空指针异常:
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.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
class 中调用时它总是导致异常。
对于 AlertDialog
上的上下文,我尝试了 ListClass.this
、getApplicationContext()
、getBaseContext()
... 我尝试在 [=31 中保存上下文=] as 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();
}
您忘记创建警报对话框,所以它为空,而不是上下文
Android simple alert dialog
从 here in answer from Dan Bray 得到了解决方案。需要使用静态上下文。
由于您是从 activity 外部调用的,因此您需要将上下文保存在 activity class:
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();
}
});
activityclass中调用的方法也必须是public static
.
我试图从另一个 class 调用一个方法,然后调用一个 AlertDialog
方法,我已经尝试了很多方法,但它总是导致空指针异常。调用 class 是 运行 一个 Web 服务器,我在 activity class 上有一个 RecyclerView
列表,其中包含被调用的方法。这是来自 activity class 和 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;
}
...
}
这是来自我的网络服务器的代码 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);
}
}
总是在这一行引起空指针异常:
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.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
class 中调用时它总是导致异常。
对于 AlertDialog
上的上下文,我尝试了 ListClass.this
、getApplicationContext()
、getBaseContext()
... 我尝试在 [=31 中保存上下文=] as 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();
}
您忘记创建警报对话框,所以它为空,而不是上下文
Android simple alert dialog
从 here in answer from Dan Bray 得到了解决方案。需要使用静态上下文。
由于您是从 activity 外部调用的,因此您需要将上下文保存在 activity class:
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();
}
});
activityclass中调用的方法也必须是public static
.