Android Activity启动模式设置为singleInstance后的跳转问题

一、出现场景

最近本人在做公司项目的时候,有一个需求就是将activity最小化,然后启动Service悬浮窗的需求,此时就必须将此Activity的启动模式设置为singleInstance,否则最小化(即调用moveTaskToBack(true)这个方法)时app直接跳至lancher界面,这样就达不到我们想要的效果。

二、新的问题

熟悉activity的四种启动模式的同学都应该清楚,当Activity启动模式设置为SingleInstance后,当start此activity时会单独开启一个任务栈,当我们有需要从此activity跳转到另一个activity处理需求的时候,就会出现我们处理完需求后finish后一个activity时,就返回不到此activity了。

不熟悉Activity启动模式的同学,要想理解此篇博文,必须先去熟悉下。网上关于这方面的资源很多,我就不多讲了。

三、解决办法

     1、参考资料:

我的解决办法是在https://blog.csdn.net/Mr_JingFu/article/details/79077613这篇文章上进行修改的,大家可以去看看,然后结合自己的需求可以进行选择。

     2、解决思路

     1)、新建一个activity的管理类,新增一个列表list,在BaseActivity中当我们打开一个activity时将此activity添加进去,关闭时将此activity时移除。

     2)、当我们关闭一个activity时,会自动调用前一个activity的onRestart——>onStart——>onResume方法,此时我们

可以在onStart方法进行判断,此activity是否与list中最后一个Activity是否为同一个,如果是就不做任何逻辑,不是的话list最后一个Activity的启动模式就有可能singleInstance,那我们就手动跳转到此Activity中,问题初步就得到解决了。

    3)、为什么说只能说是有可能呢,因为当我们将启动模式为singleInstance的Activity最小化的时候,此Activity并没有关闭,而是在后台中继续运行,此时如果我们不做任何判断的话,就会出现当我们最小化的时候,又重新打开此Activity了。原因就是此时list中最后一个Activity就是当前启动模式为singleInstance的Activity.

 4)、为解决这个问题,我们必须再添加一个启动模式为singleInstance的Activity的singleInstanceList.当启动此activity时,添加进去,关闭时和最小化的时候移除。在onstart方法中多加一层判断,当次activity与list中最后一个Activity不为同一个时,将list中的activity与singleInstanceList中的Activity进行比对,如果singleInstanceList存在此Activity,这时候这个activity就是我们所要跳转的activity,那么我们直接跳过去就可以了。值得一提的是,当我们从新打开启动模式为singleInstance的activity的时候,并不会走oncreate——>onStart()——>onResume()方法,而是走onNewIntent()——>onRestart()——>onStart()——>onResume()方法,此时我们必须得在这后面三个方法其中一个将此activity添加到singleInstanceList中。当然,我自己是在onStart方法中添加的。

3 关键代码

  1)、appManager中相关代码

public class AppManger {
    private static List<Activity> mActivityStack = new ArrayList<>();
    private static AppManger mAppManager;

    private List<Activity> mSingleInstanceStack = new ArrayList<>();

    private AppManger() {

    }


    /**
     * 单一实例
     */
    public static AppManger getInstance() {
        if (mAppManager == null) {

            synchronized (AppManger.class) {
                if (mAppManager == null) {
                    mAppManager = new AppManger();
                }
            }
        }
        return mAppManager;
    }

    public void remove(Activity activity) {
        if (activity != null) {
            mActivityStack.remove(activity);
        }
    }

    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity) {
        if (mActivityStack == null) {
            mActivityStack = new ArrayList<Activity>();
        }
        mActivityStack.add(activity);
    }

    /**
     * 添加singleInstanceActivity
     */
    public void addSingleInstanceActivity(Activity activity) {
        if (!isAddSingleInstanceActivity(activity.getClass()))
            mSingleInstanceStack.add(activity);
    }

    /**
     * 移除singleInstanceActivity
     */
    public void removeSingleInstanceActivity(Activity activity) {
        if (activity != null)
            mSingleInstanceStack.remove(activity);
    }

    public List<Activity> getmSingleInstanceStack() {
        return mSingleInstanceStack;
    }

    /**
     * 查看某个singleInstanceActivity是否被添加过
     *
     * @param cls
     */
    public boolean isAddSingleInstanceActivity(Class<?> cls) {
        int size = mSingleInstanceStack.size();
        if (size > 0)
            for (int i = size - 1; i >= 0; i--) {
                if (mSingleInstanceStack.get(i).getClass() == cls) {
                    return true;
                }
            }
        return false;
    }

    /**
     * 获取栈顶Activity(堆栈中最后一个压入的)
     */
    public Activity getTopActivity() {
        if (mActivityStack == null) {
            return null;
        }
        Activity activity = mActivityStack.get(mActivityStack.size() - 1);
        return activity;
    }

    /**
     * 结束指定的Activity
     */
    public void killActivity(Activity activity) {
        if (activity != null) {
            mActivityStack.remove(activity);
            activity.finish();
            activity = null;
        }
    }

    /**
     * 结束指定类名的Activity
     */
    public void killActivity(Class<?> cls) {
        
        int size = mActivityStack.size();
        L.e("栈内activity长度为-------------" + size);
        if (size > 0)
            for (int i = size - 1; i >= 0; i--) {
                if (mActivityStack.get(i).getClass() == cls) {
                    mActivityStack.get(i).finish();
                }
            }

    }


    /**
     * 结束所有Activity
     */
    public void killAllActivity() {
        for (int i = 0, size = mActivityStack.size(); i < size; i++) {
            if (null != mActivityStack.get(i)) {
                mActivityStack.get(i).finish();
            }
        }
        mActivityStack.clear();
    }


    /**
     * 关闭所选所以之外的activity
     */
    public void KillexceptActivitiy(Activity activity) {
        int size = mActivityStack.size();
        for (int i = size - 1; i >= 0; i--) {
            if (mActivityStack.get(i) != activity) {
                mActivityStack.get(i).finish();
            }
        }
    }

    /**
     * 查看某个activity是否被添加过
     *
     * @param cls
     */
    public boolean isAddActivity(Class<?> cls) {
        Iterator<Activity> iterator = mActivityStack.iterator();
        while (iterator.hasNext()) {
            Activity activity = iterator.next();
            if (activity.getClass().equals(cls)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 结束栈顶Activity(堆栈中最后一个压入的)
     */
    public void killTopActivity() {
        Activity activity = mActivityStack.get(mActivityStack.size() - 1);
        killActivity(activity);
    }


    /**
     * 关闭所选所以之外的activity
     */
    public void KillexceptActivitiy(Class<?> cls) {
        int size = mActivityStack.size();
        for (int i = size - 1; i >= 0; i--) {
            if (mActivityStack.get(i).getClass() != cls) {
                mActivityStack.get(i).finish();
            }
        }
    }


    /**
     * 结束到类名的Activity
     */
    public void killTOActivity(Class<?> cls) {
        for (int i = mActivityStack.size() - 1; i >= 0; i--) {
            if (null != mActivityStack.get(i)) {
                if (mActivityStack.get(i).getClass().equals(cls)) {
                    killActivity(mActivityStack.get(i));
                }
            }
        }
    }

    /**
     * 是否有打开app
     *
     * @return
     */
    public boolean isOpenActivity() {
        if (mActivityStack == null) {
            return false;
        } else if (mActivityStack.size() == 0) {
            return false;
        }
        return true;
    }


    /**
     * 退出应用程序
     */
    public void AppExit(Context context) {
        try {
            killAllActivity();
            ActivityManager activityMgr = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.restartPackage(context.getPackageName());
            System.exit(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2)BaseActivity中相关代码

@Override
protected void onStart() {
    checkInstanceActivity();
    super.onStart();
}

@Override
public void finish() {
    removeActivity();
    super.finish();
}
/**
 * 释放资源
 */
private void removeActivity() {
    AppManger.getInstance().remove(this);
}

private void checkInstanceActivity() {//判断栈顶activity
    if (AppManger.getInstance().getTopActivity() != null) {
        if (!AppManger.getInstance().getTopActivity().getClass().getName().equals(this.getClass().getName())) {
            if (AppManger.getInstance().getmSingleInstanceStack().size() > 0)
                for (int i = AppManger.getInstance().getmSingleInstanceStack().size() - 1; i >= 0; i--) {
                    if (AppManger.getInstance().getmSingleInstanceStack().get(i).getClass().getName().equals(AppManger.getInstance().getTopActivity().getClass().getName())) {
                        startActivity(AppManger.getInstance().getTopActivity().getClass(), null);
                        return;
                    }
                }
        }
    }
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    apolloBinder = Apollo.bind(this);//事件通知进行绑定
    DaggerCommonComponent.builder().netWorkMoudle(new NetWorkMoudle(this)).build().inject(this);
    ActivityCollector.addActivity(this);
    AppManger.getInstance().addActivity(this);
    //注:该方法是【友盟+】Push后台进行日活统计及多维度推送的必调用方法,请务必调用!
    PushAgent.getInstance(this).onAppStart();
}

3)启动模式有singleInstance的activity的关键用法

 

//最小化语聊房同时打开悬浮窗
public void minimizeRoom() {
    AppManger.getInstance().removeSingleInstanceActivity(this);//最小化时移除此单例activity
    moveTaskToBack(true);//最小化Activity

    Intent intent = new Intent(this, FloatChatRoomWindowService.class);//开启服务显示悬浮框
    Bundle bundle = new Bundle();
    bundle.putBoolean("sound", db.cbSound.isChecked());
    bundle.putInt("room_id", room_id);
    bundle.putString("avatar", roomInfo.getAvatar());
    intent.putExtras(bundle);

    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

    isShowFloating = true;

}
@Override
protected void onStart() {
    super.onStart();
    AppManger.getInstance().addSingleInstanceActivity(this);
}

/**
 * 内存泄漏解决方案
 * 在使用分享或者授权的Activity中,重写onDestory()方法:
 */
@Override
protected void onDestroy() {
    super.onDestroy();
    UMShareAPI.get(this).release();
    AppManger.getInstance().removeSingleInstanceActivity(this);
}

4、结束语 

虽然我话说的比较多,但是具体思路确实是这样子的。希望能帮助到大家!如果对大家有所帮助的话,请大家给个赞。

 

 

 

       

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页