在我的应用程序Widget我使用LRUCashe在内存中缓存,Picasso用于下载位图(仅限磁盘缓存),但所有相同的我得到OutOfMemory异常。请帮帮我们)
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Preferences = context.getSharedPreferences(StartOptions.WIDGET_PREF, Context.MODE_PRIVATE);
_appWidgetIds = appWidgetIds;
if(Preferences != null && Preferences.contains(StartOptions.SETTINGS_SET) && checkConnection(context)) {
for (int id : appWidgetIds) {
try {
updateWidget(context, appWidgetManager, Preferences, id);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
SharedPreferences.Editor editor =
context.getSharedPreferences(StartOptions.WIDGET_PREF, Context.MODE_PRIVATE).edit();
for (int widgetID : appWidgetIds) {
editor.remove(StartOptions.SETTINGS_SET + widgetID);
}
POSITION = 0;
editor.commit();
}
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
if(_widgetID != 0)
{
if(intent.getAction().equals(NEXT_CLICK) && POSITION < currentWidgetContent_size-1)
{
POSITION += 1;
updateIndicator();
widgetView.setTextViewText(R.id.name_tv, getTitle(POSITION));
widgetView.showNext(R.id.viewFlipper);
loadBitmap(getImg(POSITION),context);
}
else if(intent.getAction().equals(PREVIOUS_CLICK) && POSITION > 0) {
POSITION -= 1;
updateIndicator();
widgetView.setTextViewText(R.id.name_tv,getTitle(POSITION));
widgetView.showPrevious(R.id.viewFlipper);
loadBitmap(getImg(POSITION),context);
}
else if(intent.getAction().equals(ARTICAL_CLICK)) {
final Intent forStartActivityIntentARTICLE = new Intent(context, a_dumb_article.class);
forStartActivityIntentARTICLE.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(forStartActivityIntentARTICLE);
}
else if(intent.getAction().equals(ICON_CLICK)) {
final Intent forStartActivityIntentMain = new Intent(context, a_dumb_main.class);
forStartActivityIntentMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(forStartActivityIntentMain);
}
else if(intent.getAction().equals(REFRESH_CLICK)) {//пока отложу реализацию
}
}
}
@Override
public void onDisabled(Context context)
{
super.onDisabled(context);
}
private static void getFile(final String url, final Context context) throws IOException {
target = new Target()
{
@Override
public void onPrepareLoad(Drawable d) {
Bitmap loodingHeadband = ((BitmapDrawable) d).getBitmap();
widgetView.setImageViewBitmap(R.id.background_image,loodingHeadband);
widgetView.setViewVisibility(R.id.content_image_pg, View.VISIBLE);
AppWidgetManager.getInstance(context).updateAppWidget(_widgetID, widgetView);
}
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
BitmapWorkerTask task = new BitmapWorkerTask(bitmap,context);
task.execute(url);
}
@Override
public void onBitmapFailed(Drawable f){}
};
pec.load(url)
.resize(WIDGET_WIDTH, WIDGET_HEIGHT)
.placeholder(R.drawable.account_resource__fb)
.centerCrop()
.into(target);
}
public static void updateWidget(Context context, AppWidgetManager appWidgetManager,
SharedPreferences sp, int widgetID) throws IOException {
SETTINGS = sp.getInt(StartOptions.SETTINGS_SET + widgetID, 1);
Preferences = sp;
widgetView = new RemoteViews(context.getPackageName(), R.layout.main_with_picture);
setDimantion(context);
if(SETTINGS == 1 && checkConnection(context)) {
currentWidgetContent = WidgetArticle.newInstance(context).getFilling();
}
else if(SETTINGS == 2 && checkConnection(context)) {
currentWidgetContent = WidgetCover.newInstance(context).getFilling();
}
updateIndicator();
keys = new String[currentWidgetContent_size];
_appWidgetManager =appWidgetManager;
_appWidgetManager.updateAppWidget(widgetID, widgetView);
widgetView.setTextViewText(R.id.name_tv,getTitle(POSITION));
intentInit(context);
_widgetID = widgetID;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 12;
pec = new Picasso.Builder(context).memoryCache(Cache.NONE).build();
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
loadBitmap(getImg(POSITION), context);
}
private static void intentInit(Context context) {
final Intent intentNEXT = new Intent(context, BaseAppWidgetProvider.class);
intentNEXT.setAction(NEXT_CLICK);
final PendingIntent pendingIntentNEXT = PendingIntent.getBroadcast(context, 0, intentNEXT, 0);
final Intent intentPREVIOUS = new Intent(context, BaseAppWidgetProvider.class);
intentPREVIOUS.setAction(PREVIOUS_CLICK);
final PendingIntent pendingIntentPREVIOUS = PendingIntent.getBroadcast(context, 0, intentPREVIOUS, 0);
final Intent intentICON = new Intent(context, BaseAppWidgetProvider.class);
intentICON.setAction(ICON_CLICK);
final PendingIntent pendingIntentICON = PendingIntent.getBroadcast(context, 0, intentICON, 0);
final Intent intentARTICLE = new Intent(context, BaseAppWidgetProvider.class);
intentARTICLE.setAction(ARTICAL_CLICK);
final PendingIntent pendingIntentARTICLE = PendingIntent.getBroadcast(context, 0, intentARTICLE, 0);
final Intent intentREFRESH = new Intent(context, BaseAppWidgetProvider.class);
intentREFRESH.setAction(REFRESH_CLICK);
final PendingIntent pendingIntentREFRESH = PendingIntent.getBroadcast(context, 0, intentREFRESH, 0);
widgetView.setOnClickPendingIntent(R.id.next_button, pendingIntentNEXT);
widgetView.setOnClickPendingIntent(R.id.previous_button, pendingIntentPREVIOUS);
widgetView.setOnClickPendingIntent(R.id.image_i, pendingIntentICON);
widgetView.setOnClickPendingIntent(R.id.article,pendingIntentARTICLE);
widgetView.setOnClickPendingIntent(R.id.ref_button, pendingIntentREFRESH);
}
private static void setDimantion(Context context) {
WIDGET_HEIGHT = context.getResources().getDisplayMetrics().heightPixels;
WIDGET_WIDTH = context.getResources().getDisplayMetrics().widthPixels;
}
private static boolean checkConnection(Context context) {
boolean result = true;
final ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) {
result = false;
Toast.makeText(context, "подключите интернет", Toast.LENGTH_LONG).show();
}
return result;
}
private static void updateIndicator() {
currentWidgetContent_size = currentWidgetContent.size();
widgetView.setTextViewText(R.id.indicator,"("+POSITION+"/" +currentWidgetContent_size+")");
}
private static String getTitle(int position) {
return currentWidgetContent.get(position).get("title");
}
private static String getImg(int position) {
return currentWidgetContent.get(position).get("img");
}
public static void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(hashKeyForDisk(key)) == null) {
mMemoryCache.put(hashKeyForDisk(key), bitmap);
}
}
public static Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
public static void loadBitmap(String key, Context context) throws OutOfMemoryError{
final Bitmap bitmap = getBitmapFromMemCache(hashKeyForDisk(key));
if (bitmap != null) {
widgetView.setImageViewBitmap(R.id.background_image, bitmap);
widgetView.setViewVisibility(R.id.content_image_pg, View.INVISIBLE);
try{
_appWidgetManager.updateAppWidget(_widgetID, widgetView);
在这个地方我得到了OOM
}catch (IllegalArgumentException e){
}
//bitmap.recycle();
} else {
try {
getFile(key, context);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String hashKeyForDisk(String key) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey;
}
private static String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
static class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
Bitmap _bitmap;
Context _context;
public BitmapWorkerTask (Bitmap bitmap,Context context) {
_context = context;
_bitmap = bitmap;
}
@Override
protected Bitmap doInBackground(String... params) {
addBitmapToMemoryCache(params[0], _bitmap);
return _bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
try{
loadBitmap(getImg(POSITION), _context);
}catch (OutOfMemoryError oom){
}
}
}
}