Android–关闭某个指定activity

作者 : 开心源码 本文共8018个字,预计阅读时间需要21分钟 发布时间: 2022-05-12 共163人阅读

最近项目中有这样的需要,在关闭当前Activity同时关闭前面两个Activity,不涉及到应用的退出。自己想了少量方案,也查了少量资料,做个笔记吧。

方案一

广播的方式

这个是最容易想到的,同时也是网上提供最多的。 因为多个Activity要使用,关闭页面的广播最好写在基类BaseActivity中,也可以在各个子页面单独写,但是代码量就添加了。

public class BaseActivity extends Activity {    //根据需求定义自己需要关闭页面的action    public static final String RECEIVER_ACTION_FINISH_A = "receiver_action_finish_a";    public static final String RECEIVER_ACTION_FINISH_B = "receiver_action_finish_b";    public static final String RECEIVER_ACTION_FINISH_C = "receiver_action_finish_c";    public static final String RECEIVER_ACTION_FINISH_D = "receiver_action_finish_d";    private FinishActivityRecevier mRecevier;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mRecevier = new FinishActivityRecevier();        registerFinishReciver();    }    private void registerFinishReciver() {        IntentFilter intentFilter = new IntentFilter();        intentFilter.addAction(RECEIVER_ACTION_FINISH_A);        intentFilter.addAction(RECEIVER_ACTION_FINISH_B);        intentFilter.addAction(RECEIVER_ACTION_FINISH_C);        intentFilter.addAction(RECEIVER_ACTION_FINISH_D);        registerReceiver(mRecevier, intentFilter);    }    private class FinishActivityRecevier extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            //根据需求增加自己需要关闭页面的action            if (RECEIVER_ACTION_FINISH_A.equals(intent.getAction()) ||                    RECEIVER_ACTION_FINISH_B.equals(intent.getAction()) ||                    RECEIVER_ACTION_FINISH_C.equals(intent.getAction()) ||                    RECEIVER_ACTION_FINISH_D.equals(intent.getAction())) {                BaseActivity.this.finish();            }        }    }    @Override    protected void onDestroy() {        if (mRecevier != null) {            unregisterReceiver(mRecevier);        }        super.onDestroy();    }}

发送广播就需要在各个需求子Activity中进行了,这里使用工具类,方便以后屡次或者者拓展使用,只要要在需求子Activity中直接调用就行。

public class BroadcastUtils {    /**     * 发送finish页面的广播     * action可以自己根据需要增加     * @param context     */    public static void sendFinishActivityBroadcast(Context context) {        Intent intent = new Intent(BaseActivity.RECEIVER_ACTION_FINISH_B);        context.sendBroadcast(intent);        intent = new Intent(BaseActivity.RECEIVER_ACTION_FINISH_C);        context.sendBroadcast(intent);    }}

优劣:

优点:最常规使用,不会出现内存泄漏,在基类中操作,代码量不多。
缺点:项目中若是需要关闭页面多的话,需要发送大量广播,会降低性能。

方案二

直接static activity方式

这是网上提供的,代码一看就显著的内存泄漏。但是。。。。。。

private static AActivity sInstance;    public static AActivity getInstance() {        if (sInstance != null) {            return sInstance;        }        return null;    }    public static void finishActivity() {        if (sInstance != null) {            sInstance.finish();        }    }

内存泄漏显著,之所以有但是,那是由于这种方式让我想到加入弱引用WeakReference的方式。

public class BActivity extends BaseActivity {    private static WeakReference<BActivity> sActivityRef;    public static void finishActivity() {        if (sActivityRef != null && sActivityRef.get() != null) {            sActivityRef.get().finish();        }    }    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_b);        sActivityRef = new WeakReference<>(this);        Button btnB = (Button) findViewById(R.id.btn_b);        btnB.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                startActivity(new Intent(BActivity.this, CActivity.class));            }        });    }}

WeakReference以及JVM相关,尽管WeakReference被static了,生命周期变长了,但是WeakReference关联的对象不受影响的,仍然遵循WeakReference在gc时候的规则。
优劣: 优点:代码简单直观,引入WeakReference,处理了内存泄漏问题。 缺点:在每个activity中都要增加,代码量多。(不知能否可抽取到基类中,以后尝试)

方案三

使用集合或者者栈的方式

public class FinishActivityManager {    private FinishActivityManager() {    }    private static FinishActivityManager sManager;    private List<Activity> activityList;    public static FinishActivityManager getManager() {        if (sManager == null) {            synchronized (FinishActivityManager.class) {                if (sManager == null) {                    sManager = new FinishActivityManager();                }            }        }        return sManager;    }    /**     * 增加Activity到集合中     */    public void addActivity(Activity activity) {        if (activityList == null) {            activityList = new LinkedList<>();        }        activityList.add(activity);    }    /**     * 关闭指定的Activity     */    public void finishActivity(Activity activity) {        if (activityList != null && activity != null && activityList.contains(activity)) {            //使用迭代器安全删除            for (Iterator<Activity> it = activityList.iterator(); it.hasNext(); ) {                Activity temp = it.next();                // 清除掉已经释放的activity                if (temp == null) {                    it.remove();                    continue;                }                if (temp == activity) {                    it.remove();                }            }            activity.finish();        }    }    /**     * 关闭指定类名的Activity     */    public void finishActivity(Class<?> cls) {        if (activityList != null) {            // 使用迭代器安全删除            for (Iterator<Activity> it = activityList.iterator(); it.hasNext(); ) {                Activity activity = it.next();                // 清除掉已经释放的activity                if (activity == null) {                    it.remove();                    continue;                }                if (activity.getClass().equals(cls)) {                    it.remove();                    activity.finish();                }            }        }    }    /**     * 关闭所有的Activity     */    public void finishAllActivity() {        if (activityList != null) {            for (Iterator<Activity> it = activityList.iterator(); it.hasNext(); ) {                Activity activity = it.next();                if (activity != null) {                    activity.finish();                }            }            activityList.clear();        }    }    /**     * 退出应用程序     */    public void exitApp() {        try {            finishAllActivity();            // 退出JVM,释放所占内存资源,0表示正常退出            System.exit(0);            // 从系统中kill掉应用程序            android.os.Process.killProcess(android.os.Process.myPid());        } catch (Exception e) {            e.printStackTrace();        }    }}

这种方式注意在删除的时候使用迭代器,否则会出现并发修改异常。 那就来说说但是,应用中要是不使用这种封装的方式去finish掉Activity的时候,封装的manager并不知道,没有断开并释放掉其引用,会引起内存泄漏。所以WeakReference又要出场了。

public class FinishActivityManager {    private FinishActivityManager() {    }    private static FinishActivityManager sManager;    private Stack<WeakReference<Activity>> mActivityStack;    public static FinishActivityManager getManager() {        if (sManager == null) {            synchronized (FinishActivityManager.class) {                if (sManager == null) {                    sManager = new FinishActivityManager();                }            }        }        return sManager;    }    /**     * 增加Activity到栈     * @param activity     */    public void addActivity(Activity activity) {        if (mActivityStack == null) {            mActivityStack = new Stack<>();        }        mActivityStack.add(new WeakReference<>(activity));    }    /**     * 检查弱引用能否释放,若释放,则从栈中清除掉该元素     */    public void checkWeakReference() {        if (mActivityStack != null) {            // 使用迭代器进行安全删除            for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {                WeakReference<Activity> activityReference = it.next();                Activity temp = activityReference.get();                if (temp == null) {                    it.remove();                }            }        }    }    /**     * 获取当前Activity(栈中最后一个压入的)     * @return     */    public Activity currentActivity() {        checkWeakReference();        if (mActivityStack != null && !mActivityStack.isEmpty()) {            return mActivityStack.lastElement().get();        }        return null;    }    /**     * 关闭当前Activity(栈中最后一个压入的)     */    public void finishActivity() {        Activity activity = currentActivity();        if (activity != null) {            finishActivity(activity);        }    }    /**     * 关闭指定的Activity     * @param activity     */    public void finishActivity(Activity activity) {        if (activity != null && mActivityStack != null) {            // 使用迭代器进行安全删除            for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {                WeakReference<Activity> activityReference = it.next();                Activity temp = activityReference.get();                // 清除掉已经释放的activity                if (temp == null) {                    it.remove();                    continue;                }                if (temp == activity) {                    it.remove();                }            }            activity.finish();        }    }    /**     * 关闭指定类名的所有Activity     * @param cls     */    public void finishActivity(Class<?> cls) {        if (mActivityStack != null) {            // 使用迭代器进行安全删除            for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {                WeakReference<Activity> activityReference = it.next();                Activity activity = activityReference.get();                // 清除掉已经释放的activity                if (activity == null) {                    it.remove();                    continue;                }                if (activity.getClass().equals(cls)) {                    it.remove();                    activity.finish();                }            }        }    }    /**     * 结束所有Activity     */    public void finishAllActivity() {        if (mActivityStack != null) {            for (WeakReference<Activity> activityReference : mActivityStack) {                Activity activity = activityReference.get();                if (activity != null) {                    activity.finish();                }            }            mActivityStack.clear();        }    }    /**     * 退出应用程序     */    public void exitApp() {        try {            finishAllActivity();            // 退出JVM,释放所占内存资源,0表示正常退出            System.exit(0);            // 从系统中kill掉应用程序            android.os.Process.killProcess(android.os.Process.myPid());        } catch (Exception e) {            e.printStackTrace();        }    }}

代码一目了然,之所以改成Stack,是由于要模仿Activity的任务栈的方式,关闭最后打开的Activity更加方便。 使用的话,在BaseActivity中onCreate()中addActivity,在onDestroy()中finishActivity(),其余功能在各个子Activity中根据需要增加。

优劣:

优点:一劳永逸,一次封装,方便后续使用。
缺点:暂无。

方案四

使用Activity的launchMode

根据Android启动模式,standard和singleTop并不能实现项目需求,故排除。

singleTask和singleInstance在使用的时候会和onActivityResult()有点关系: Android 5.0以上的版本能正常使用,没有冲突; Android 5.0以下的版本有个bug,在调用了startActivityForResult之后立马就会调用onActivityResult,不会等到打开的Activity返回的时候才调用。 项目中很多Activity种都有startActivityForResult,故此种方式排除掉。

方案五

使用onActivityResult方式

根据方案四,此方式需要配合launchMode的standard和singleTop使用才能达到效果,所以局限性很大。

方案六

使用Rxbus

Rxbus也是可以实现的,根据自己的需求来决定吧
要是项目中需要关闭Activity不多,不需要发送大量广播,可以使用方案一;方案二和方案三有殊途同归之处,首先推荐方案三;比较之下我在项目中用了方案三。

【附】相关架构及资料

加群 Android IOC架构设计领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起探讨交流处理问题。

Android高级技术大纲

领取方式:

点赞+加群免费获取 Android IOC架构设计

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Android–关闭某个指定activity

发表回复