Timmo
Timmo

Reputation: 2334

Set TextView in Handler And Thread Widget

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

Answers (1)

Greg Giacovelli
Greg Giacovelli

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

Related Questions