您的位置:首页 > 移动开发 > Android开发

Android 在安装完成界面,点击打开应用程序。在应用程序点击home键,再从桌面打开程序导致产生多个实例或者说程序被重复打开。(为了把问题写清楚,标题一定要长长长........)

2014-04-04 23:09 429 查看
本博纯属个人开发记录,

转载请注明出处:/article/9656818.html

问题标题都已经写明了,就是在普通的安装apk完成之后,会遇到的一种情况。基本上在程序的AndroidManifest.xml里面没有对Activity的属性做特殊处理都会出现这种情况,具体现象可以自己写个demo安装看看。

原理:

为了了解问题产生的原因,首先,我们先来讲一下Android的任务栈的机制:

任务栈就是用来存放应用程序的Activity的地方,Android默认在打开应用程序的时候给每个应用单独分配一个任务栈,用来管理应用程序Activity间的跳转,返回。每个Activity都可以配置一个属性叫taskAffinity,每个Activity默认的taskAffinity是以应用程序的包名命名的,为什么要提到这个呢,这个点后面会讲到,接下去看。

一般来说,每个应用都单独跑在自己的任务栈上,但是我们也可以让两个应用程序跑在同一个任务栈里面。我们可以从一个应用程序里面启动跳转到另一个应用程序里面。跳转的代码一般有两种写法:

代码1:从程序1跳转到程序2之后,两个应用程序是跑在同一个任务栈里面的。

Intent intent=new Intent("android.intent.action.MAIN");
intent.setComponent(new ComponentName("com.et.demo","com.et.demo.TestActivity"));
startActivity(intent);


代码2:从程序1跳转到程序2之后,两个应用程序是跑在各自的任务栈里面的。

Intent intent=new Intent("android.intent.action.MAIN");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(new ComponentName("com.et.demo","com.et.demo.TestActivity"));
startActivity(intent);


一开始我以为桌面的打开方式和安装完成界面的打开方式不同在于Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)这句话上,之后看了下源码,发现其实两者差不多,基本上都有加New_Task这句话,所以我也搞不明白为什么出现打开方式错误的问题。(之前搞错了。。。囧)。

不过,解决方案已经出炉了,所以秉着先解决问题的原则,我们先上解决方案。(呵呵,这是什么原则!)

解决方法:

接下来呢,各位童鞋,我们来学习一个词,叫“曲线救国”。好吧,方法的确是有点曲线,但是效果不错,上菜。

思路:

1、先在你的应用程序里新建一个Activity,将它设置为首页(你懂de),让它跑在独立的Task上面。

2、将这个Activity作为跳转页面,新建Task(代码2)跳转到你的程序“真正”的首页上(你又懂de),销毁掉这个Activity,连带它的Task。

3、这样你的程序就跑在了自己独立的Task上面了,就不会出现打开多个实例的问题了。

实现:

新建FirstActivity,在manifest配置属性(最重要的部分

<activity
android:name="com.example.opentest.FirstActivity"
android:configChanges="keyboardHidden|orientation|fontScale"
android:label="@string/title_activity_first"
android:excludeFromRecents="true"
android:taskAffinity="com.example.opentest.first"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
</intent-filter>
</activity>


我的程序包名是com.example.opentest,这里我们将FirstActivity的属性设置一下



android:taskAffinity="com.example.opentest.first"



这样是为了让它自己跑在独立的Task上。(你自己好好反省一下吧,哼)。

而另一个重要的属性:

android:excludeFromRecents="true"

作用是隐藏Task(即让你的Task不出现在长按home出现的界面里)。

然后在FirstActivity代码中:

Intent intent=new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();


新建任务栈跳转到我的“真正”首页,销毁自己(自我牺牲精神——哎哟,不错哦)。

这样的做法其实就是自己写个跳转页面,然后在跳转页面写自己的跳转方式,保证自己的程序的打开方式和Launcher一样。同时在用完这个Activity的时候finish它,顺便隐藏它的Task。

这样就解决了程序重复打开的问题了。但是这样就行了么? nonono,图样。这样做在每次打开应用的时候动画效果会很差,会出现跳转两次的闪屏,不信你试试。

要怎么做呢,我们先把FirstActivity中的setContentView的代码直接删掉,然后在style文件里面写个style

<style name="WindowIsTranslucent">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@+android:style/Animation.Translucent</item>
</style>


android:windowIsTranslucent:Activity背景透明。

android:windowAnimationStyle你可以指定你的Activity的加载动画。

然后在manifest里将FirstActivity的theme指定一下就可以了。这样出来的效果就好很多了。虽然解决方法有点取巧,但是效果还不错。

总结一下,虽然问题不是很常见,解决方法也不是特别难,但是对于一个软件来说,第一次打开的时候出现程序问题肯定会给用户一个很不好的印象。目前很多app(像百度视频,hao123浏览器什么的)都还有存在这个问题,上网找了一下,发现都没有解决方案,既然解决了就跟大家分享一下。

最后,完整的demo已放出,各位看官觉得好的请点赞。

下载地址:http://download.csdn.net/detail/etong_123/7148307
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐