我正在尝试在 Textview
上执行 setText()
(已在 onCreate()
中实例化),由 Handler
并使用 ruiOnUiTread()
但我在 Textview
上有一个 nullPointerException
。
问题从何而来?
我在调试中看到 activity
的实例在实例化和 setText() 之间不同,虽然我没有更改 activity
但无法实例化它与 setText()
位于同一位置。
private TextView ambianceTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ambianceTextView = findViewById(R.id.valeur_ambiance);
StarterKillerPidroid.getInstance().startApp();
}
private final Runnable retrieveData = new Runnable() {
public void run() {
try {
setText();
} catch (Exception e) {
e.printStackTrace();
}
handlerRecup.postDelayed(retrieveData, 1000);
}
};
public void setText(){
runOnUiThread(new Runnable() {
@Override
public void run() {
ambianceTextView.setText("test");
}
});
}
public void doAfterLogin() {
handlerRecup.postDelayed(retrieveData, 10000);
}
可运行程序由 Volley 的 http 请求回调调用的函数启动
公共(public)类 StarterKillerPidroid {
void startApp() {
//Sending a request
PostmanPidroid.getInstance().login();
}
public void ackLogin(Boolean isValid) {
if (isValid) {
ActivityMain.getInstance().doAfterLogin();
} else {
PostmanPidroid.getInstance().login();
}
}
}
postman 类:
public class Postman {
public void login(){
// Parameters
String email = "test@tes";
String password = "test";
// Encoding the request with parameters
JsonObjectRequest request = EncoderDecoderPidroid.getInstance()
.encodeRequestLogin(email, password);
// Sending the request
sendRequest(request);
}
void sendRequest(StringRequest message){
// Creating the queu if it's not create
if (queue == null) {
queue = Volley.newRequestQueue(context);
}
// Adding the request to the queue
queue.add(message);
}
}
当收到成功响应时,调用此回调:
private Response.Listener<JSONObject> callbackLogin =
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
...
StarterKillerPidroid.getInstance().ackLogin(true);
}
};
最佳答案
基本上,这种问题是由于实例造成的。您的 textview 实例可能未初始化。还有一件事是,直接使用处理程序来更新 UI 线程并不是一个好主意。您应该使用 FunctionalInterface
来执行此操作,而不是直接使用处理程序更新 Ui。
FunctionalInterface
对于这种情况是一个很好的方法。
A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit. From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. ... Runnable, ActionListener, Comparable are some of the examples of functional interfaces.
Java 有一个预定义的FunctionalInterface
Callable
。事情是这样的
public static void doDid(final Callable<Void> callable) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
callable.call();
handler.postDelayed(this, every * repeattime);
} catch (Exception e) {
e.printStackTrace();
}
}
}, every * tempvalue);
}
并以这种方式使用它来更新 UI
doDid(new Callable<Void>() {
@Override
public Void call() {
textView.setText("Your text");
return null;
}
});
有一个适用于 Android 的开源库,在这种情况下它的工作方式就像一个魅力,称为 Predictor
。您可以从here下载并导入到您的项目中。您还可以在此项目中做出贡献,以挽救许多开发人员的生命。
你想看看预测器如何做到这一点吗?
Predictor.every(3).second().doDid(new Job<Void>() {
@Override
public Void run() {
textView.setText("Your text");
return null;
}
});
你可以用预测器做什么?
Predictor 为您提供了几种处理多线程的方法,其中一些方法如下:
Predictor.every(3).second().doDid(something());
Predictor.every(5).minutes().doDid(something());
Predictor.every().hour().doDid(something());
Predictor.every().week().doDid(something());
Predictor.every().month().doDid(something());
还有更多...
关于java - 在处理程序上调用时, TextView 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50883569/