我声明了一个界面:
public interface GetChildList{
public void onGetChildList(List<String> list);
}
在我的班级(我称之为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
}
}
以下是我的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();
}
一切正常,我在ChildActivity
onGetChildList
方法中获取列表。
但我想在list
中填充listview
,如下所示:
@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
}
但我得到例外android.view.viewrootimpl$calledfromwrongthreadexception
请建议我,等待回复。
由于
答案 0 :(得分:0)
尝试使用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();
}
答案 1 :(得分:0)
问题是您尝试从新的 onGetChildList(List<String> list)
调用Thread
方法。你不能这样做,因为你需要在UI上完成的所有工作都必须从主线程(有时称为UI线程)执行。您可以阅读更多相关信息here
我建议您在此处创建新的AsyncTask,并将run
方法中的所有代码移到doInBackground()
方法的最后一行。最新的行需要在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();
它将起作用,因为doInBackground()
方法在后台线程内执行,当此方法完成时,AsyncTask
将其结果传递给正在UI线程上执行的onPostExecute
。 AsyncTask
专门用于此类任务 - 在后台执行某些操作,然后使用结果更新UI。