从服务器获取JSON,这是我的ListView的内容。 一切都很好,但我想在Json被调用时创建一个ProgressDialog。 问题是我需要在不同的线程中调用JSON(使用http方法)并在ListView中向用户显示结果。
这是我在做什么,但我得到错误"05-09 12:13:28.358: W/System.err(344): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views."
try {
final ProgressDialog progDailog;
progDailog =ProgressDialog.show(this,"HI", "Loading");
new Thread(new Runnable() {
@Override
public void run() {
try
{
JSONArray json = new JSONArray(executeHttpGet("http://m-devsnbp.insightlabs.cl/cuentos/json"));
progDailog.cancel();
ArrayList<HashMap<String, String>> talesList = new ArrayList<HashMap<String, String>>();
talesList = jsonToHash(json);
adapter = new LazyAdapter((Activity) ctx, talesList, 2);
list.setAdapter(adapter);
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
如何从其他主题更新我的观点?或者这是一个更好的方法吗?
答案 0 :(得分:3)
您需要在主ui线程上更新ui。使用runOnUiThread
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
progDailog.cancel();
adapter = new LazyAdapter((Activity) ctx, talesList, 2);
list.setAdapter(adapter);
}
});
还要考虑使用asynctask。我建议ypu使用asynctask
http://developer.android.com/reference/android/os/AsyncTask.html
ProgressDialog pd;
LazyAdapter adapter;
ListView list;
ArrayList<HashMap<String, String>> talesList = new ArrayList<HashMap<String, String>>();
在你的活动onCreate()
pd = new ProgressDialog(ActivityName.this);
pd.setTitle("Processing...");
new TheTask().execute();
将AsyncTask定义为活动类中的内部类
class extends AsyncTask<Void,Void,Void>
{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd.show();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try
{
JSONArray json = new JSONArray(executeHttpGet("http://m-devsnbp.insightlabs.cl/cuentos/json"));
talesList = jsonToHash(json);
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
adapter = new LazyAdapter(AcctivityName.this, talesList, 2);
list.setAdapter(adapter);
}
}
答案 1 :(得分:0)
当您尝试从非UI线程更新视图时,需要通过post()方法更新它:
try {
final ProgressDialog progDailog;
progDailog =ProgressDialog.show(this,"HI", "Loading");
Thread mThread = new Thread(new Runnable() {
@Override
public void run() {
try
{
JSONArray json = new JSONArray(executeHttpGet("http://m-devsnbp.insightlabs.cl/cuentos/json"));
progDailog.cancel();
ArrayList<HashMap<String, String>> talesList = new ArrayList<HashMap<String, String>>();
talesList = jsonToHash(json);
adapter = new LazyAdapter((Activity) ctx, talesList, 2);
list.setAdapter(adapter);
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
post(mThread);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
答案 2 :(得分:0)
Modyfing Views只能在UI Thread上进行,所以对我来说,你应该尝试使用一个处理Activity引用的类并传递runnable来运行
class UIUpdater{
private static UIUpdater mInstance;
private Activity mActivity;
public static UIUpdater getInstance()
{
if(mInstance == null){
mInstance = new UIUpdater();
}
return mInstance;
}
public void runOnUiThread(Runnable run){
mActivity.runOnUiThread(run);
}
}
另一种方法是使用Loopers: 例如
Looper mMainLooper = Looper.getMainLooper();
有关详细信息,请参阅here
答案 3 :(得分:0)
我认为有更好的方法可以做到这一点。就像使用AsyncTask
一样这只是您想要做的代码示例。
private class LongOperation extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
private ArrayList<HashMap<String, String>> talesList;
private LazyAdapter adapter;
private Context mContext;
public LongOperation(Context c) {
mContext = c;
progressDialog = new ProgressDialog(c);
}
@Override
protected void onPreExecute() {
//operation start, show the dialog
progressDialog.show();
}
@Override
protected String doInBackground(Void... params) {
//connect to server and get json
try
{
JSONArray json = new JSONArray(executeHttpGet("http://m-devsnbp.insightlabs.cl/cuentos/json"));
talesList = new ArrayList<HashMap<String, String>>();
talesList = jsonToHash(json);
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onPostExecute(Void result) {
//operation end, dismiss the dialog and set result to list
progressDialog.dismiss();
adapter = new LazyAdapter(mContext, talesList, 2);
list.setAdapter(adapter);
}
}
您可能想看一些链接: