Android--关闭某个指定activity

最近项目中有这样的须要,在关闭当前Activity同时关闭前面两个Activity,不涉及到应用的退出。本身想了一些方案,也查了一些资料,作个笔记吧。html

方案一

广播的方式

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

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);
    }
}

复制代码

优劣: 有点:最常规使用,不会出现内存泄漏,在基类中操做,代码量很少。 缺点:项目中如果须要关闭页面多的话,须要发送大量广播,会下降性能。bash

方案二

直接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的方式。ide

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中根据须要添加。ui

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

方案四

使用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很少,不须要发送大量广播,可使用方案一;方案二和方案三有殊途同归之处,首先推荐方案三;比较之下我在项目中用了方案三。

参考文章:www.jcodecraeer.com/a/anzhuokai…

相关文章
相关标签/搜索