我想用第二只手表创建一个时钟小部件。 是的,我已经读过,小部件不是为了快速刷新而设计的。
小部件应该成为一个蛋计时器,只有当用户主动启动它时才会生成动画,因此它可能对电池寿命和性能没有那么差,因为我只在用户主动使用它时使用这种高刷新率。
目前我启动的服务每1000毫秒发布一次延迟的runnable。
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”。 对于这个异常,我没有堆栈跟踪,但我想这是因为我不回收我新创建的位图。 之后的例外是:“系统服务器死了?”这里我有一个堆栈跟踪:
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
我认为只需回收我的位图就可以轻松解决这个问题
if (bmpLast != null) {
bmpLast.recycle();
}
bmpLast = bmpSource;
但这只是让我想到下一个问题:
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)
我已经缓存了我的最后一个位图,只有当新的位图被转发到小部件时才回收它。为什么我会得到这个例外?
谁想要包裹我的最后一个位图?保持小部件对我传入的所有位图的引用???
干杯, 斯蒂芬
答案 0 :(得分:1)
你应该像这样回收位图
if (bmpLast != null) {
bmpLast.recycle();
bmpLast=null;//you must do it
}
除此之外还有另一个问题,你应该使用alarmmanager更新小部件,与Runnable()相比,它会减少电量;
答案 1 :(得分:1)
您的部分问题可能是您挂在RemoteViews
对象上并继续向其添加“操作”。 RemoteViews
不执行任何智能重复操作,只是将它们附加到列表中,因此您可以有效地保留对您推送的每个Bitmap
的引用。