My app uses the CallLog to collect data and put it into a listview. As this takes time, I tried to use progressdialog to show the user the status of the loading. Unfortunately (I have used progressdialog before) eclipse throws me an error: ERROR/AndroidRuntime(771): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
public class Calls extends Activity {
//declaring variables
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calls);
lv1 = (ListView) findViewById(R.id.ListView01);
pd = new ProgressDialog(Calls.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Loading contacts");
pd.show();
//Thread thread = new Thread() {
//public void run() {
Calls.this.runOnUiThread(new Runnable() {
@Override
开发者_StackOverflow中文版 public void run() {
//collecting data from CallLog, putting data into an array
//Here comes the hard part, which is the root of the problem:
final ArrayList<SearchResults> results = new ArrayList<SearchResults>();
SearchResults sr1 = new SearchResults();
for (int b=0; b<storage.length; b++)
{
for (int e=0; e<storage[b].length; e++)
{
if (e+3 < storage[b].length)
{
arr_split_all.add(storage[b][e] + " " + storage[b][e+1] + " " + storage[b][e+2] + " " + storage[b][e+3]);
sr1 = new SearchResults();
sr1.setData1(storage[b][e+2]);
sr1.setData2(storage[b][e]);
sr1.setData3(storage[b][e+1]);
sr1.setData4(storage[b][e+3]);
sr1.setBitmap2(bitmaparray[b]); //bitmaparray has the same size as storage, and there is no problem with this
results.add(sr1);
}
}
}
lv1.setAdapter(new MyCustomBaseAdapter(Calls.this, results)); //problematic row
handler.sendEmptyMessage(0);
}
};
thread.start();
}
}//end of onCreate
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
pd.dismiss();
}
}); //ADDED a )
}//end of class
// SearchResults is another class:
public class SearchResults extends Application{
private String data1 = "";
private String data2 = "";
private String data3 = "";
private String data4 = "";
private String bitmap = "";
private Bitmap bitmap2;
public void setData1(String data1) {
this.data1 = data1;
}
public String getData1() {
return data1;
}
//etc...
}
And I am using a BaseAdapter class to put the data into the appropriate places of the listview (which consists of an imageview and four textviews), but I don't think that is relevant now.
According to Logcat, the problem is with the lv1.setAdapter(new MyCustomBaseAdapter(Calls.this, results));
row. If I attach an arraylist to the listview, it is working fine. Without the progressdialog all textviews and the imageview of each row of the listview is loaded properly.
The problem is your findViewById()
call to your ListView01
(and later on, the setAdapter()
call). You cannot modify (or access) views from a custom thread. This has to be done on the UI thread, either via runOnUiThread()
or in a place where the UI thread runs.
精彩评论