android开发笔记之WeakReference和SoftRefrerence

简单的说明

WeakReference:弱引用–>随时可能会被垃圾回收器回收,不一定要等到虚拟机内存不足时才强制回收。要获取对象时,同样可以调用get方法。所以WeakReference一般用来防止内存泄漏,要保证内存被虚拟机回收。

SoftReference:软引用–>当虚拟机内存不足时,将会回收它指向的对象;需要获取对象时,可以调用get方法。所以,SoftReference多用作来实现缓存机制(cache)

例子

我们以packages目录下的应用为例子,可以查看到此目录下WeakReference和SoftReference 使用情况:

—- WeakReference Matches (284 in 88 files) —-
WeakReference 在88个文件,使用了284次

—- SoftReference Matches (71 in 13 files) —-
SoftReference 在13个文件,使用了71次

从上面可以看出,WeakReference 的使用比SoftReference 更常用。

WeakReference

第一个例子:

ZenRuleSelectionDialog.java (apps\settings\src\com\android\settings\notification):

在AsyncTask中更新R.id.icon的ImageView的图片:

    private class LoadIconTask extends AsyncTask<ApplicationInfo, Void, Drawable> {
        private final WeakReference<ImageView> viewReference;

        public LoadIconTask(ImageView view) {
            viewReference = new WeakReference<>(view);
        }

        @Override
        protected Drawable doInBackground(ApplicationInfo... params) {
            return params[0].loadIcon(mPm);
        }

        @Override
        protected void onPostExecute(Drawable icon) {
            if (icon != null) {
                final ImageView view = viewReference.get();
                if (view != null) {
                    view.setImageDrawable(icon);
                }
            }
        }
    }

使用方法:

LoadIconTask task = new LoadIconTask((ImageView) v.findViewById(R.id.icon));

task.execute(info);

此方法是对R.id.icon的ImageView来使用WeakReference,以防止内存泄漏。

第二个例子:
AddAccessoryActivity.java (apps\tvsettings\settings\src\com\android\tv\settings\accessories):

定义static内部类MessageHandler :

    private static class MessageHandler extends Handler {

        private WeakReference<AddAccessoryActivity> mActivityRef = new WeakReference<>(null);

        public void setActivity(AddAccessoryActivity activity) {
            mActivityRef = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            final AddAccessoryActivity activity = mActivityRef.get();
            if (activity == null) {
                return;
            }
            switch (msg.what) {
                case MSG_UPDATE_VIEW:
                    activity.updateView();
                    break;
                case MSG_REMOVE_CANCELED:
                    activity.mCancelledAddress = ADDRESS_NONE;
                    activity.updateView();
                    break;
                case MSG_PAIRING_COMPLETE:
                    activity.finish();
                    break;
                case MSG_OP_TIMEOUT:
                    activity.handlePairingTimeout();
                    break;
                case MSG_RESTART:
                    if (activity.mBluetoothPairer != null) {
                        activity.mBluetoothPairer.start();
                        activity.mBluetoothPairer.cancelPairing();
                    }
                    break;
            ...........

使用:

    // Internal message handler
    private final MessageHandler mMsgHandler = new MessageHandler();
..................
mMsgHandler.setActivity(this);
..................
mMsgHandler.removeCallbacksAndMessages(null);
..................
mMsgHandler.sendEmptyMessageDelayed(MSG_OP_TIMEOUT, timeout);
..................

此例子为常用的m内部Handler类的对activity的弱引用的例子。

第三个例子:
BluetoothBipCoverArt.java (apps\bluetooth\src\com\android\bluetooth\bip):

private static class RemoteControllerWeak implements RemoteController.OnClientUpdateListener {
        //定义弱引用
        private final WeakReference<Handler> mLocalHandler;

        public RemoteControllerWeak(Handler handler) {
            //弱引用赋值
            mLocalHandler = new WeakReference<Handler>(handler);
        }

..........................

        @Override
        public void onClientMetadataUpdate(MetadataEditor metadataEditor) {
            Handler handler = mLocalHandler.get();
            if (handler != null) {
                handler.obtainMessage(MSG_SET_METADATA, 0, 0, metadataEditor).sendToTarget();
            }
        }
............................

使用方法:

mRemoteControllerCb = new RemoteControllerWeak(mBipCoverArtHandler);

此例子,主要是对mBipCoverArtHandler实现弱引用。

SoftReference

第一个例子:

KeyboardLayoutSet.java (inputmethods\latinime\java\src\com\android\inputmethod\keyboard)

定义一个static的缓存HashMap:

private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
            new HashMap<>();

实现此缓存的效果:

private Keyboard getKeyboard(final ElementParams elementParams, final KeyboardId id) {
        //先判断是否存在缓存
        final SoftReference<Keyboard> ref = sKeyboardCache.get(id);
        final Keyboard cachedKeyboard = (ref == null) ? null : ref.get();
        if (cachedKeyboard != null) {
            if (DEBUG_CACHE) {
                Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": HIT  id=" + id);
            }
            return cachedKeyboard;
        }
.........
    //给其赋值
    sKeyboardCache.put(id, new SoftReference<>(keyboard));
.........

清除缓存:

    private static void clearKeyboardCache() {
        sKeyboardCache.clear();
        ...........
    }

第二个例子:
Sources.java (experimental\loaderapp\src\com\android\loaderapp\model):

public class Sources extends BroadcastReceiver implements OnAccountsUpdateListener {
................
    private static SoftReference<Sources> sInstance = null;
................
    public static synchronized Sources getInstance(Context context) {
        Sources sources = sInstance == null ? null : sInstance.get();
        if (sources == null) {
            sources = new Sources(context);
            sInstance = new SoftReference<Sources>(sources);
        }
        return sources;
    }
................

这个软引用实现缓存的实现非常明显

参考资料

1.Android中的软引用(SoftRefrerence)和弱引用(WeakReference)
http://blog.csdn.net/stevenhu_223/article/details/18360397
2.WeakReference在Android中的使用
http://blog.csdn.net/u012951554/article/details/48055939
3.Java弱引用(WeakReference)的理解与使用
http://blog.csdn.net/zmx729618/article/details/54093532

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hfreeman2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值