每秒重绘小部件 [英] Redraw Widget every second

查看:153
本文介绍了每秒重绘小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用秒针创建一个时钟小部件. 是的,我已经读过,小部件并非旨在如此快地刷新.

I want to create a clock widget with a second watch hand. And yes, I already read that widgets aren't designed to be refreshed that fast.

该小部件应该成为Egg计时器,仅当用户主动启动它时才对其进行动画处理,因此这对电池寿命和性能可能并没有那么糟糕,因为我仅在用户积极使用它时才使用这种高刷新率.

The widget should become an egg timer which is only animated when the user actively starts it so it is probably not that bad for battery life and performance at all because I only use this high refresh rate when the user actively uses it...

当前,我启动了一项服务,该服务每1000毫秒发布一次延迟的可运行时间.

Currently I start a service which posts a delayed runnable every 1000 milliseconds.

Handler mTimeRecordLongTouchedHandler = new Handler();
Runnable mTimeRecordLongTouched = new Runnable() {
    public void run() {

        remoteViews.setTextViewText(R.id.tv_widget_watch, _fmtTime.print(new DateTime()));
        Bitmap bmpSource = _bmpSource.copy(Bitmap.Config.ARGB_8888, true);

        Canvas canvas = new Canvas(bmpSource);


        DateTime dtNow = new DateTime();
        int iSeconds = dtNow.getSecondOfMinute();

        float radius = _bmpSource.getWidth() / 2;
        float mX = _bmpSource.getWidth() / 2;
        float mY = _bmpSource.getWidth() / 2;

        float pX = mX + radius * FloatMath.cos(iSeconds * 6);
        float pY = mY + radius * FloatMath.sin(iSeconds * 6);

        canvas.drawLine(mX, mY, pX, pY, paint3);

        remoteViews.setImageViewBitmap(R.id.iv_tower, bmpSource);

        manager.updateAppWidget(thiswidget, remoteViews);
        iCounter++;

        // if (bmpLast != null) {
        // bmpLast.recycle();
        // }
        // bmpLast = bmpSource;

        mTimeRecordLongTouchedHandler.postDelayed(mTimeRecordLongTouched, 1000);
    }
};

几秒钟后,我得到:"android.os.TransactionTooLargeException". 对于这种例外情况,我没有堆栈跟踪,但是我想这是因为我没有回收新创建的位图. 此后的异常是:系统服务器死了吗?"在这里,我有一个堆栈跟踪:

After a few seconds I get: "android.os.TransactionTooLargeException". For this exception I don’t have a stack trace but I guess it is because I don’t recycle my newly created bitmap. The exception after this is: "system server dead?" and here I have a stacktrace:

03-07 11:26:28.374: E/AndroidRuntime(13422): FATAL EXCEPTION: main
03-07 11:26:28.374: E/AndroidRuntime(13422): java.lang.RuntimeException: system server dead?
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.appwidget.AppWidgetManager.updateAppWidget(AppWidgetManager.java:554)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at com.mxp.time.service.WidgetService$1.run(WidgetService.java:90)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.os.Handler.handleCallback(Handler.java:730)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.os.Looper.loop(Looper.java:137)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.app.ActivityThread.main(ActivityThread.java:5493)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at java.lang.reflect.Method.invokeNative(Native Method)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at java.lang.reflect.Method.invoke(Method.java:525)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at dalvik.system.NativeStart.main(Native Method)
03-07 11:26:28.374: E/AndroidRuntime(13422): Caused by: android.os.TransactionTooLargeException
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.os.BinderProxy.transact(Native Method)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.updateAppWidgetProvider(IAppWidgetService.java:736)
03-07 11:26:28.374: E/AndroidRuntime(13422):    at android.appwidget.AppWidgetManager.updateAppWidget(AppWidgetManager.java:551)
03-07 11:26:28.374: E/AndroidRuntime(13422):    ... 10 more

我认为只要回收位图就可以轻松解决此问题

I thought that I can solve this easily with just recycling my bitmap

if (bmpLast != null) {
            bmpLast.recycle();
        }
        bmpLast = bmpSource;

但这只会导致我遇到下一个问题:

but this just leads me to the next problem:

03-07 11:28:22.964: E/AndroidRuntime(14559): FATAL EXCEPTION: main
03-07 11:28:22.964: E/AndroidRuntime(14559): java.lang.IllegalStateException: Can't parcel a recycled bitmap
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.graphics.Bitmap.checkRecycled(Bitmap.java:273)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.graphics.Bitmap.writeToParcel(Bitmap.java:1332)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.widget.RemoteViews$BitmapCache.writeBitmapsToParcel(RemoteViews.java:988)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.widget.RemoteViews.writeToParcel(RemoteViews.java:2573)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.updateAppWidgetProvider(IAppWidgetService.java:730)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.appwidget.AppWidgetManager.updateAppWidget(AppWidgetManager.java:551)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at com.mxp.time.service.WidgetService$1.run(WidgetService.java:90)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.os.Handler.handleCallback(Handler.java:730)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.os.Looper.loop(Looper.java:137)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at android.app.ActivityThread.main(ActivityThread.java:5493)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at java.lang.reflect.Method.invokeNative(Native Method)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at java.lang.reflect.Method.invoke(Method.java:525)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
03-07 11:28:22.964: E/AndroidRuntime(14559):    at dalvik.system.NativeStart.main(Native Method)

我已经缓存了我的最后一个位图,并且仅在将新位图转发到窗口小部件时才对其进行回收.为什么会出现此异常?

I already cache my last bitmap and only recycle it when the new one is forwarded to the widget. Why do I get this exception?

谁想包裹我的最后一个位图?保持小部件对我传递的所有位图的引用??

Who wants to parcel my last Bitmap? Keeps the widget a reference to all Bitmaps I pass in???

干杯, 斯蒂芬

推荐答案

部分问题可能是您坚持使用RemoteViews对象并继续向其中添加操作". RemoteViews不会对操作进行任何智能的重复数据删除,它只是将它们添加到列表中,因此您可以有效地保留对每个推入其中的Bitmap的引用.

Part of your problem is probably that you hang on to your RemoteViews object and keep adding 'actions' to it. RemoteViews doesn't do any smart de-duplication of actions, it just appends them to a list, so you're effectively retaining references to every Bitmap you push into it.

这篇关于每秒重绘小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆