[英]android.view.viewrootimpl$calledfromwrongthreadexception android java
I have Declare an interface: 我有一个接口声明:
public interface GetChildList{
public void onGetChildList(List<String> list);
}
In my class (where I call fetchJSONChild()
) implement: 在我的类中(我称之为
fetchJSONChild()
)实现:
import com.example.hakslogin.GetChildList;
public class ChildActivity extends ActionBarActivity implements GetChildList {
Button btn_home;
Button btn_add;
private HandleJSON obj;
public String urlString = "http://192.168.x.xx:xxxx/getdb";
List<String> child = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_child);
obj = new HandleJSON(urlString);
child = obj.fetchJSONChild(this);
}
@Override
public void onGetChildList(List<String> list) {
//this method will be called after thread in fetchJSONChild ended
child = list;
//here you can work with your list
}
}
Below is my fetchJSONChild
: 以下是我的
fetchJSONChild
:
public void fetchJSONChild(final GetChildList callBack){
final List<String> child = new ArrayList<String>();
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
try {
URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000 /* milliseconds */);
conn.setConnectTimeout(50000 /* milliseconds */);
conn.setRequestMethod("GET");
//conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
//conn.setUseCaches (false);
// Starts the query
if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
conn.setRequestProperty("Connection", "close");
}
conn.connect();
System.out.println("Before url.openStream()");
InputStream stream = conn.getInputStream();//.openStream();
System.out.println("After url.openStream()");
String data = convertStreamToString(stream);
// for examole data = "1,2,3";
child.addAll(Arrays.asList(data.split(","));
readAndParseJSON(data);
stream.close();
callBack.onGetChildList(child);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
All working fine and I am getting list on my ChildActivity
in onGetChildList
method. 一切正常,我通过
onGetChildList
方法获取有关ChildActivity
列表。
But I want to populate list
in the listview
like below: 但是我想在
list
listview
填充list
,如下所示:
@Override
public void onGetChildList(List<String> list) {
//this method will be called after thread in fetchJSONChild ended
List<String> array = new ArrayList<String>();
child = list;
//onCreate(new Bundle());
lv_child = (ListView)findViewById(R.id.lv_child);
String arr[]=child.toArray(new String[list.size()]);
String[] Temp= new String[2];
Temp[0] = arr[2].toString();
array.add(Temp[0].split(":")[1]);
String s = Temp[0].toString();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
lv_child.setAdapter(adapter);
//here you can work with your list
}
But I am getting exception android.view.viewrootimpl$calledfromwrongthreadexception
但我收到异常
android.view.viewrootimpl$calledfromwrongthreadexception
Kindly suggest me, waiting for reply. 请建议我,等待回复。
Thanks 谢谢
Try to use AsyncTask instead to Thread for get data from server : 尝试使用AsyncTask代替Thread从服务器获取数据:
public void fetchJSONChild(final GetChildList callBack){
new AsyncTask<Void,Void,List<String>>(){
@Override
protected List<String> doInBackground(Void... params) {
List<String> child = new ArrayList<String>();
try {
URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(30000 /* milliseconds */);
conn.setConnectTimeout(50000 /* milliseconds */);
conn.setRequestMethod("GET");
//conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoInput(true);
//conn.setUseCaches (false);
// Starts the query
if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
conn.setRequestProperty("Connection", "close");
}
conn.connect();
System.out.println("Before url.openStream()");
InputStream stream = conn.getInputStream();//.openStream();
System.out.println("After url.openStream()");
String data = convertStreamToString(stream);
// for examole data = "1,2,3";
child.addAll(Arrays.asList(data.split(",")));
readAndParseJSON(data);
stream.close();
}catch (Exception e){
e.printStackTrace();
}
return child;
}
@Override
protected void onPostExecute(List<String> child) {
super.onPostExecute(child);
callBack.onGetChildList(child);
}
}.execute();
}
The issue is that you're trying to invoke onGetChildList(List<String> list)
method from the new Thread
. 问题是您正在尝试从新
Thread
调用onGetChildList(List<String> list)
方法。 You can't do that, because all the work that needs to be done on your UI has to performed from the main thread (sometimes called UI thread). 您不能这样做,因为在UI上需要完成的所有工作都必须从主线程(有时称为UI线程)执行。 You can read more about it here .
您可以在此处了解更多信息。
I suggest you create new AsyncTask here and move all your code inside the run
method except for the last line to its doInBackground()
method. 我建议您在此处创建新的AsyncTask并将所有代码移到
run
方法中,除了最后一行到其doInBackground()
方法。 The latest line needs to be moved inside the AsyncTask#onPostExecute
method, so the whole structure looks like this: 最新行需要在
AsyncTask#onPostExecute
方法内移动,因此整个结构如下所示:
new AsyncTask<Void,Void,List<String>>(){
@Override
protected List<String> doInBackground(Void... params) {
List<String> child = new ArrayList<String>();
try {
// code omitted for brevity
}catch (Exception e){
e.printStackTrace();
}
return child;
}
@Override
protected void onPostExecute(List<String> child) {
super.onPostExecute(child);
callBack.onGetChildList(child);
}
}.execute();
It will work because doInBackground()
method executes inside the background thread and when this method finishes, AsyncTask
passes its result to the onPostExecute
which is being executed on the UI thread. 之所以会起作用,是因为
doInBackground()
方法在后台线程内执行,并且此方法完成后, AsyncTask
会将其结果传递给在UI线程上执行的onPostExecute
。 AsyncTask
was made specifically for this kind of tasks - do something in background, then update UI with the results. AsyncTask
专为此类任务而制作-在后台执行某些操作,然后使用结果更新UI。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.