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

本博纯属个人开发记录, 

转载请注明出处:http://blog.youkuaiyun.com/etong_123/article/details/22897731


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

               原理:

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

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

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

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent=new Intent("android.intent.action.MAIN");  
  2.         intent.setComponent(new ComponentName("com.et.demo","com.et.demo.TestActivity"));  
  3.         startActivity(intent);  

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent=new Intent("android.intent.action.MAIN");  
  2.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  3.         intent.setComponent(new ComponentName("com.et.demo","com.et.demo.TestActivity"));  
  4.         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配置属性(最重要的部分

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <activity  
  2.             android:name="com.example.opentest.FirstActivity"  
  3.             android:configChanges="keyboardHidden|orientation|fontScale"  
  4.             android:label="@string/title_activity_first"  
  5.             android:excludeFromRecents="true"  
  6.             android:taskAffinity="com.example.opentest.first"  
  7.             android:windowSoftInputMode="adjustPan" >  
  8.             <intent-filter>  
  9.                 <action android:name="android.intent.action.MAIN" />  
  10.   
  11.                 <category android:name="android.intent.category.LAUNCHER" />  
  12.             </intent-filter>  
  13.             <intent-filter>  
  14.                 <action android:name="android.intent.action.CREATE_SHORTCUT" />  
  15.             </intent-filter>  
  16.         </activity>  

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

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

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

       而另一个重要的属性:

        android:excludeFromRecents="true"

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

     然后在FirstActivity代码中:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Intent intent=new Intent(this, MainActivity.class);  
  2. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  3. startActivity(intent);  
  4.              finish();  

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

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

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

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <style name="WindowIsTranslucent">  
  2.       <item name="android:windowIsTranslucent">true</item>  
  3.       <item name="android:windowAnimationStyle">@+android:style/Animation.Translucent</item>  
  4.     </style>  

     android:windowIsTranslucent:Activity背景透明。

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

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

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

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

        下载地址:http://download.youkuaiyun.com/detail/etong_123/7148307

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值