昨晚上在进行http请求获取数据并修改listview的时候遇到了一个问题Only the original thread that created a view hierarchy can touch its views
大概意思就是:只有创建了视图层级的原始线程才可以修改这个视图
于是我百度了一下,然后大概解决方案是这样子的,子线程通过handler传值给主线程,主线程接收后,再进行修改listview。
代码语言:javascript复制Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
Bundle data = msg.getData();
String val = data.getString("value");
//设置UI
tvCode.setText(val);
Log.i(TAG, "请求结果:" val);
} else if (msg.what ==0) {
Toast.makeText(getApplicationContext(),"请求资源不成功",Toast.LENGTH_LONG).show();
}
}
};
/**
* 处理网络请求的线程
*/
private class RequestThread extends Thread {
@Override
public void run() {
//网络请求
String string = 请求结果
Message msg = new Message();
Bundle data = new Bundle();
//将获取到的String装载到msg中
data.putString("value", string);
msg.setData(data);
msg.what = 1;
//发消息到主线程
handler.sendMessage(msg);
}
}
//点击事件启动新线程
public void test(View v){
new RequestThread().start();
}
解决方法原链接:https://blog.csdn.net/LJX_ahut/article/details/89432576
经过实践着实有用。
获取前:
获取后:
MainActivity.java代码
代码语言:javascript复制package ink.cik.logininfoapp;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.net.wifi.aware.DiscoverySession;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.List;
import ink.cik.logininfoapp.eneity.userInfo;
import ink.cik.logininfoapp.help.httpHelper;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private final Gson gson = new Gson();
@SuppressLint("HandlerLeak")
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
Bundle data = msg.getData();
String val = data.getString("value");
List<userInfo> userInfoList = parseJson(val);
ListView listView = (ListView) findViewById(R.id.listInfo);
ArrayList<String> list = new ArrayList<String>();//数据源集合创建
for (userInfo userInfo : userInfoList) {
list.add(userInfo.getUserName());
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_list_item_1, list
);
listView.setAdapter(adapter);
} else if (msg.what == 0) {
Toast.makeText(MainActivity.this, "数据获取失败,请检查网络!", Toast.LENGTH_SHORT);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.searchButton);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getAll();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
private void getAll() {
final httpHelper httpHelper = new httpHelper();
new Thread(new Runnable() {
@Override
public void run() {
try {
String res = httpHelper.httpGet("https://api.565.ink/login/getAll?passwd=lanol666");
Log.d("结果:", res);
Message msg = new Message();
Bundle data = new Bundle();
//将获取到的String装载到msg中
data.putString("value", res);
msg.setData(data);
msg.what = 1;
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private List<userInfo> parseJson(String JsonData) {
Gson gson = new Gson();
List<userInfo> userInfoList = gson.fromJson(JsonData, new TypeToken<List<userInfo>>() {
}.getType());
return userInfoList;
}
}