Android小部件上的线程
Posted
技术标签:
【中文标题】Android小部件上的线程【英文标题】:Threads on Android widget 【发布时间】:2018-09-06 04:55:57 【问题描述】:我正在尝试制作一个小部件时钟。
在我的 MainActivity 上,时钟使用 runOnUiThread 完美显示。 由于小部件不扩展“活动”,我无法运行 OnUiThread。 但是当我尝试将 Thread 与小部件一起使用时,我收到错误(或)一个空白小部件。
public class NewAppWidget extends AppWidgetProvider
static Context cont;
static AppWidgetManager awm;
static int awid;
static Thread t;
static RemoteViews views;
static String timeText;
static String dateText;
public static Bitmap BuildUpdate(String txttime, int size,Context context)
Paint paint= new Paint();
paint.setTextSize(size);
Typeface
custTface=Typeface.createFromAsset(context.getAssets(),"fonts/Lato-Regular.ttf");
paint.setTypeface(custTface);
paint.setColor(Color.WHITE);
paint.setTextAlign(Paint.Align.LEFT);
paint.setSubpixelText(true);
paint.setAntiAlias(true);
// - in the next line is highly important.
float baseline = -paint.ascent();
int width =(int) paint.measureText(txttime+0.5f);
int height= (int) (baseline+paint.descent()+0.5f);
Bitmap image = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(image);
canvas.drawText(txttime,0,baseline,paint);
return image;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId)
views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
cont=context;
awm=appWidgetManager;
awid=appWidgetId;
t = new Thread()
@Override
public void run()
while (!isInterrupted())
try
t.sleep(1000);
new Thread(new Runnable()
@Override
public void run()
long date = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat sdf2 = new SimpleDateFormat("hh-mm-ss a");
timeText = sdf2.format(date);
dateText = sdf.format(date);
views.setImageViewBitmap(R.id.txtTime, BuildUpdate(timeText, 100, cont));
views.setImageViewBitmap(R.id.txtDate, BuildUpdate(dateText, 25, cont));
awm.updateAppWidget(awid, views);
);
catch (InterruptedException e)
;
t.start();
这会产生一个空白小部件。
我不是要代码,只是帮我找出我在这里的错误以及我应该如何处理?
【问题讨论】:
【参考方案1】:您的Thread
方法不起作用,因为android 不允许未创建View
层次结构的Thread
s 接触那些View
s。与大多数情况一样,您尝试从工作人员 Thread
更新的 View
很可能在 Android 的 Activity
创建过程中在 UI 线程上被夸大和实例化。
我认为你有两个选择:
始终将Activity
作为Context
参数传递给NewAppWidget
构造函数。
然后您可以安全地将Context
对象转换为Activity
并调用Activity.runOnUiThread(Runnable)
,或者将Context
字段更改为Activity
,以避免每次都进行转换。
使用Handler
。
如下实例化您的Handler
。这将创建一个链接到 UI 线程(也称为“主”线程)的 Handler
对象。
Handler handler = new Handler(Looper.getMainLooper());
然后,您可以使用 Handler
发布 Runnable
s,然后您的工作人员 Thread
在 UI Thread
上运行。您可以通过这种方式从您的工作人员Thread
更新View
s:
handler.post(new Runnable() ... );
我推荐第二种方法,因为它更简洁,而且您不需要通过这种方式引用 Activity
。
请记住第二种方法,在您的Runnable
中,您需要将WeakReference
用于您想要更新的Activity
或View
,以防止内存泄漏。即使您的Activity
或View
被(应该)垃圾收集,您的工作人员Thread
可能仍在运行。使用WeakReference
允许垃圾收集器收集您的Activity
/ View
,即使您的工作人员Thread
仍在运行。
【讨论】:
这有帮助。谢谢!以上是关于Android小部件上的线程的主要内容,如果未能解决你的问题,请参考以下文章