我尝试setText()
Textview
(已onCreate()
中已实例化)Handler
并使用ruiOnUiTread()
进行nullPointerException
但我在Textview
上有一个activity
。
问题出在哪里?
我在调试中看到activity
的实例在实例化和setText()之间不一样,而我没有更改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);
}
。
void startApp() {
//Sending a request
PostmanPidroid.getInstance().login();
}
public void ackLogin(Boolean isValid) {
if (isValid) {
ActivityMain.getInstance().doAfterLogin();
} else {
PostmanPidroid.getInstance().login();
}
}
runnable由一个使用Volley
的回调调用的函数启动 公共类StarterKillerPidroid { 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);
}
};
收到成功回复后,将调用此回调:
RootClass
答案 0 :(得分:2)
基本上,这种问题是由于实例引起的。您的textview实例可能未初始化。直接使用处理程序更新UI线程的另一件事不是一个好主意。代替使用处理程序直接更新Ui,您应该使用FunctionalInterface
进行此操作。
FunctionalInterface
是处理此类情况的好方法。
功能接口是仅包含一个抽象方法的接口。他们只能展示一种功能。从Java 8开始,lambda表达式可用于表示功能接口的实例。 ... Runnable,ActionListener和Comparable是功能接口的一些示例。
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);
}
,并以此方式更新用户界面
doDid(new Callable<Void>() {
@Override
public Void call() {
textView.setText("Your text");
return null;
}
});
有一个适用于Android的开放源代码库,其工作原理很像Predictor
这样的符咒。您可以从one from Microsoft下载它并导入到您的项目中。您也可以为这个项目做出贡献,以挽救许多开发人员的生命。
您想看看预测变量如何做到这一点吗?
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());
还有更多...
答案 1 :(得分:0)
尝试这种方式:
private final Runnable retrieveData = new Runnable() {
public void run() {
try {
ambianceTextView = (TextView) findViewById(R.id.valeur_ambiance);
setText();
} catch (Exception e) {
e.printStackTrace();
}
handlerRecup.postDelayed(retrieveData, 1000);
}
};