我有一个正在运行的线程并向服务器发出请求,并根据服务器的响应我更改了应用程序中几个元素的颜色。问题是:我需要更改活动,线程必须继续运行才能在这个新活动中发出请求但是当我来到主要活动,我需要再次为这些元素着色时,它不会画它们。我知道这是因为当线程首次在主活动中创建时,它有一个引用保持在威胁范围内的主要活动,当我离开活动时它会销毁它然后当我回来时引用是新的但我在线程上工作的活动的参考是旧的,我在调试模式下测试并发现了。
线程的代码就是这个:
public void initiateThreads(final boolean fromDisplayThread){
if(!fromDisplay){
t1= new Thread(new Runnable() {
@Override
public void run() {
final TextView text=(TextView) findViewById(R.id.textView);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
String url = "XX.XX.XX.XX";
Log.i("DREG", "onLoadMoreItems: " + url);
final StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
System.out.println(response);
text.setText(response);
try {
JSONObject res = new JSONObject(response);
String FRONT = res.getString("FRONT");
String BACK= res.getString("BACK");
String LEFT = res.getString("LEFT");
String RIGHT = res.getString("RIGHT");
setWarningLevel(FRONT, BACK, LEFT, RIGHT);
setDelay();
visualWarning(FRONT, BACK, LEFT, RIGHT);
} catch (final JSONException e) {
text.setText(e);
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (error instanceof NetworkError) {
} else if (error instanceof ServerError) {
} else if (error instanceof AuthFailureError) {
} else if (error instanceof ParseError) {
} else if (error instanceof NoConnectionError) {
} else if (error instanceof TimeoutError) {
Toast.makeText(getApplicationContext(),
"Oops. Timeout error!",
Toast.LENGTH_LONG).show();
text.setText(error);
}
}
}
);
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
10000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(stringRequest);
}
}, 0, 2000);
}
});
t1.start();
}
绘制元素的函数是visualWarning()
,代码是:
public void visualWarning(String FRONT, String BACK, String LEFT, String RIGHT){
switch (FRONT) {//FRONT
case "NONE":
ImageView imageViewIcon1 = (ImageView) findViewById(R.id.imageView1);
imageViewIcon1.setColorFilter(Color.parseColor("#0000D3"));
ImageView imageViewIcon2 = (ImageView) findViewById(R.id.imageView2);
imageViewIcon2.setColorFilter(Color.parseColor("#0000D3"));
ImageView imageViewIcon3 = (ImageView) findViewById(R.id.imageView3);
imageViewIcon3.setColorFilter(Color.parseColor("#0000D3"));
ImageView imageViewIcon4 = (ImageView) findViewById(R.id.imageView4);
imageViewIcon4.setColorFilter(Color.parseColor("#0000D3"));
//SWITCH STAEMENT CONTINUES BUT IT'S ALL THE SAME JUST CHANGING COLOR
}
如何更新当前在线程内运行的活动?
答案 0 :(得分:1)
在后台线程中保持对活动的引用通常很糟糕。您需要的是事件,您可以使用LocalBroadcasts,每当您从服务器接收数据时向您的活动发送广播,您将在正在运行的活动中接收广播。
确保在活动的onDestroy中取消注册广播
答案 1 :(得分:0)
使用runOnUiThread
在主线程上执行您的部分代码
public void onResponse(String response) {
try {
....
runOnUiThread(() -> visualWarning(FRONT, BACK, LEFT, RIGHT));
}
}