I found this example here on how to use the runOnUiThread
method, but I don't understand how to use it.
I setup the list adapter in my main activity
// Set a gobal reference to the list adapter and the list respectivly
ListAdapter listAdapter;
static ArrayList<String> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// some code
adapter = new ListAdapter(getActivity(), R.layout.item_layout, list);
listView.setAdapter(adapter);
// some code
}
I have the list adapter here calling a service handler class
public class ListAdapter {
// some code
ServiceHandler sh = new ServiceHandler();
sh.run();
}
Here is .run()
method in ServiceHandler
class where I updated the list and the list adapter
public void run(Adapter listAdapter, ArrayList<String> list){
// some code
list[0] = "foo";
listAdapter.notifyDataSetChanged;
}
But I get this error in run time
Only the original thread that created a view hierarchy can touch its views.
So I try to solve the error with .runOnUiThread
So here is .run()
method in ServiceHandler
class again, with runOnUiThread
public void run(Adapter listAdapter, ArrayList<String> list){
// some code
runOnUiThread(new Runnable() {
@Override
public void run() {
list[0] = "foo";
listAdapter.notifyDataSetChanged;
});
}
But I get
Cannot resolve method 'runOnUiThread(anonymous Java.lang.runnable)'
You can move service handler as private member class inside your activity like below to use Activity's this context.
class MyActivity extends Activity {
private class ServiceHandler /** Whichever class you extend */ {
public void run() {
MyActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
}
private MyListAdapterTracks mAdapter;
private ServiceHandler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Some code
mAdapter = new MyListAdapterTracks(getActivity(), R.layout.item_layout, list);
listView.setAdapter(mAdapter);
// Some code
ServiceHandler sh = new ServiceHandler();
sh.run();
}
}
EDIT:
public class ServiceHandler /** Whichever class you extend */ {
private final Activity mActivity;
private final MyListAdapterTracks mAdapter;
public ServiceHandler(Activity activity, MyListAdapterTracks adapter) {
mActivity = activity;
mAdapter = adapter;
}
@Override
public void run() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
// More code
}
And then instanciate it in your activity like this:
class MyActivity extends Activity {
private MyListAdapterTracks mAdapter;
private ServiceHandler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Some code
ServiceHandler sh = new ServiceHandler(this);
sh.run();
}
}
I have the same problem, and I replaced runOnUiThread()
with getActivity().runOnUiThread()
. And it worked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With