Android上的App Widget,显示大量的位图

时间:2014-02-19 16:51:50

标签: android bitmap android-appwidget

在我的应用程序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){

        }

    }
}

}

0 个答案:

没有答案