Reputation: 2334
How do I set TextView inside handlers?
public class DigitalClock extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
int N = appWidgetIds.length;
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.digitalclock);
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Intent clockIntent = new Intent(context, DeskClock.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
clockIntent, 0);
views.setOnClickPendingIntent(R.id.rl, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
private static Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// update your textview here.
}
};
class TickThread extends Thread {
private boolean mRun;
@Override
public void run() {
mRun = true;
while (mRun) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mHandler.sendEmptyMessage(0);
}
}
}
Im supposed to update the TextView here:
private static Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// update your textview here.
...
How do i do this? In the OnUpdate
method i would use views.setTextViewText(R.id...
but in the Handler
RemoteViews doesnt exist. Ive tried everything I know and so far, nothing
Upvotes: 1
Views: 610
Reputation: 10184
Make a new one :) RemoteViews just attached to the remote entity and you pretty much queue up a bunch of changes that it makes when it is realized.
So when you do
appWidgetManager.updateAppWidget(appWidgetId, views);
That is when the RemoteViews actually do something.
I think the real problem is that the design being used is a little messy. So you have a thread, not sure where this gets started but it calls into a handler, this is fine, but you should probably send some structured data so the Handler knows what to do. RemoteViews instances themselves are Parcelable, which means they can be sent as part of the payload of things such as Intent and Message instances. The real problem with this design is that you can't call updateAppWidget without the AppWidgetManager instance to actually execute your changes.
You can either cache the AppWidgetManager for the lifetime of your widget or update the update frequency and move to more of a delayed queue worker. Where on next update event that you receive from the system, or a mixture of both.
private SparseArray<RemoteView> mViews;
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
....
for (int appWidgetId : appWidgetIds) {
RemoteViews v = mViews.get(appWidgetId);
if (v != null) {
appWidgetManager.updateWidget(appWidgetId, v);
} else {
enqueue(appWidgetManager, appWidgetId, new RemoteViews(new RemoteViews(context.getPackageName(),
R.layout.digitalclock)));
/* Enqueue would pretty much associate these pieces of info together
and update their contents on your terms. What you want to do is up
to you. Everytime this update is called though, it will attempt to update
the widget with the info you cached inside the remote view.
*/
}
}
}
Upvotes: 1