Android 小部件位图错误
Android Widget Bitmap Error
当我用模拟器测试我的小部件时一切正常,但是当我尝试在真实设备 (HTC Desire 816g) 上测试它时,当我从 url 加载图像时出现以下错误.
这是错误:
05-03 12:15:21.679 24313-24393/com.example.macos.ladderapp D/dalvikvm: Alloc : 11653456
05-03 12:15:21.680 24313-24393/com.example.macos.ladderapp I/dalvikvm: "AsyncTask #2" prio=5 tid=31 RUNNABLE
| group="main" sCount=0 dsCount=0 obj=0x424d34d0 self=0x637abb60
| sysTid=24393 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1668947712
| state=R schedstat=( 93174539 4489846 39 ) utm=9 stm=0 core=1
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
05-03 12:15:21.682 24313-24393/com.example.macos.ladderapp I/dalvikvm: at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:649)
at com.example.macos.ladderapp.RetrieveFeedTask.doInBackground(RetrieveFeedTask.java:57)
at com.example.macos.ladderapp.RetrieveFeedTask.doInBackground(RetrieveFeedTask.java:25)
at android.os.AsyncTask.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
这是 Java 代码:
protected void onPostExecute(Bitmap bm) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mcontext);
RemoteViews remoteViews = new RemoteViews(mcontext.getPackageName(), R.layout.simple_widget);
remoteViews.setImageViewBitmap(R.id.REKLAM, bm);
appWidgetManager.updateAppWidget(new ComponentName(mcontext, SimpleWidgetProvider.class), remoteViews);
}
@Override
protected Bitmap doInBackground(Context... contexts) {
Bitmap bm = null;
try {
URL aURL = new URL(mLink);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e(TAG, "Error getting bitmap", e);
}
return bm;
}
这是小部件布局文件,我认为它会导致
加载小部件时出现问题
错误。我正在尝试加载一个 Imageview (REKLAM) 并在它的左上角有一个可点击的箭头向量 (clickview)。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin"
>
<ImageView
android:id="@+id/clickview"
android:layout_width="50dp"
android:alpha="0.84"
android:layout_alignLeft="@id/REKLAM"
android:src="@drawable/ic_widget_arrow_24dp"
android:layout_height="40dp" />
<ImageView
android:id="@+id/REKLAM"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</RelativeLayout>
手动处理位图有很多陷阱。我真的建议不要为一般用途推出自己的。
Google推荐的图片处理库是Glide。它带有一个方便的 class 专门用于在应用程序小部件中显示图像视图:AppWidgetTarget。
AppWidgetTarget awt = new AppWidgetTarget(context, R.id.img_dog, remoteViews, appWidgetIds) {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
super.onResourceReady(resource, transition);
}
};
RequestOptions options = new RequestOptions().
override(300, 300).placeholder(R.drawable.placeholder_img).error(R.drawable.error_img)
Glide.with(context.getApplicationContext())
.asBitmap()
.load(imageUrl)
.apply(options)
.into(awt);
在Gradle中需要添加以下几行:
implementation 'com.github.bumptech.glide:glide:4.7.1'
kapt 'com.github.bumptech.glide:compiler:4.7.1'
但关于例外情况,post 解释了使用位图时的一些陷阱:
使用 Glide,可以使用上面显示的 override() 调整图像大小。
另外,2 次险胜:
bis.close();
is.close();
需要放在 finally 块中。任何时候在 try 语句中调用 close() 时,无论它是流、游标还是其他资源,它都应该是一个潜在的危险信号。将它们放在最后几乎总是更好。
Do Input/Output Streams Get Closed on Destruction
当我用模拟器测试我的小部件时一切正常,但是当我尝试在真实设备 (HTC Desire 816g) 上测试它时,当我从 url 加载图像时出现以下错误. 这是错误:
05-03 12:15:21.679 24313-24393/com.example.macos.ladderapp D/dalvikvm: Alloc : 11653456
05-03 12:15:21.680 24313-24393/com.example.macos.ladderapp I/dalvikvm: "AsyncTask #2" prio=5 tid=31 RUNNABLE
| group="main" sCount=0 dsCount=0 obj=0x424d34d0 self=0x637abb60
| sysTid=24393 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1668947712
| state=R schedstat=( 93174539 4489846 39 ) utm=9 stm=0 core=1
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
05-03 12:15:21.682 24313-24393/com.example.macos.ladderapp I/dalvikvm: at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:649)
at com.example.macos.ladderapp.RetrieveFeedTask.doInBackground(RetrieveFeedTask.java:57)
at com.example.macos.ladderapp.RetrieveFeedTask.doInBackground(RetrieveFeedTask.java:25)
at android.os.AsyncTask.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
这是 Java 代码:
protected void onPostExecute(Bitmap bm) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mcontext);
RemoteViews remoteViews = new RemoteViews(mcontext.getPackageName(), R.layout.simple_widget);
remoteViews.setImageViewBitmap(R.id.REKLAM, bm);
appWidgetManager.updateAppWidget(new ComponentName(mcontext, SimpleWidgetProvider.class), remoteViews);
}
@Override
protected Bitmap doInBackground(Context... contexts) {
Bitmap bm = null;
try {
URL aURL = new URL(mLink);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e(TAG, "Error getting bitmap", e);
}
return bm;
}
这是小部件布局文件,我认为它会导致
加载小部件时出现问题 错误。我正在尝试加载一个 Imageview (REKLAM) 并在它的左上角有一个可点击的箭头向量 (clickview)。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin"
>
<ImageView
android:id="@+id/clickview"
android:layout_width="50dp"
android:alpha="0.84"
android:layout_alignLeft="@id/REKLAM"
android:src="@drawable/ic_widget_arrow_24dp"
android:layout_height="40dp" />
<ImageView
android:id="@+id/REKLAM"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</RelativeLayout>
手动处理位图有很多陷阱。我真的建议不要为一般用途推出自己的。
Google推荐的图片处理库是Glide。它带有一个方便的 class 专门用于在应用程序小部件中显示图像视图:AppWidgetTarget。
AppWidgetTarget awt = new AppWidgetTarget(context, R.id.img_dog, remoteViews, appWidgetIds) {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
super.onResourceReady(resource, transition);
}
};
RequestOptions options = new RequestOptions().
override(300, 300).placeholder(R.drawable.placeholder_img).error(R.drawable.error_img)
Glide.with(context.getApplicationContext())
.asBitmap()
.load(imageUrl)
.apply(options)
.into(awt);
在Gradle中需要添加以下几行:
implementation 'com.github.bumptech.glide:glide:4.7.1'
kapt 'com.github.bumptech.glide:compiler:4.7.1'
但关于例外情况,post 解释了使用位图时的一些陷阱:
使用 Glide,可以使用上面显示的 override() 调整图像大小。
另外,2 次险胜:
bis.close();
is.close();
需要放在 finally 块中。任何时候在 try 语句中调用 close() 时,无论它是流、游标还是其他资源,它都应该是一个潜在的危险信号。将它们放在最后几乎总是更好。
Do Input/Output Streams Get Closed on Destruction