Activity的启动模式和悬浮窗

原文:http://blog.csdn.net/linghu_java/article/details/17266603

在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。

  Android总Activity的启动模式分为四种:

复制代码
Activity启动模式设置:

        <activity android:name=".MainActivity" android:launchMode="standard" />

Activity的四种启动模式:

    1. standard

        默认启动模式,每次激活Activity时都会创建Activity,并放入任务栈中。

    2. singleTop

        如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例)。

    3. singleTask

        如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。 

    4. singleInstance

        在一个新栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。
复制代码


       大家遇到一个应用的Activity供多种方式调用启动的情况,多个调用希望只有一个Activity的实例存在,这就需要Activity的onNewIntent(Intent intent)方法了。只要在Activity中加入自己的onNewIntent(intent)的实现加上Manifest中对Activity设置lanuchMode=“singleTask”就可以。

       onNewIntent()非常好用,Activity第一启动的时候执行onCreate()---->onStart()---->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()---->onResart()------>onStart()----->onResume().  如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()---->onStart()---->onResume()等。

     当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

原文:http://blog.sina.com.cn/s/blog_5033827f0100xb3c.html

1.onNewIntent(Intent intent) 是Activity类的方法.它被调用发几种情况如下:

<activity android:name=".NewIntentDemo" android:label="@string/app_name"                         android:launchMode="singleTask">

 

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

 android:launchMode="singleTask" 配置在 Mainifest 中,它保证了栈中此Activity总是只有一个,无论你启动它多少次;

Activiy配置成android:launchMode="singleTask" ,在点Home键退出Activity而再次启动新的Intent进来时onNewIntent(Intent intent) 方法会被调用到;

2.利用已有的Acivity去处理别的Intent时,你就可以利用onNewIntent来处理,通常被用在有搜索请求的activity,而其该activity有好几个intent-filter,该方法被调用的前提

a、该activity设置如下属性 android:launchMode="singleTop"。
b、该activity已经处在栈的顶端,通过其他的方法又重新启动该acitvity时被调用,如搜索,这时oncreate()方法不调用。

详细实例如下:

在Map应用中会经常见到一个浮动的搜索框 一般可以搜索附近的POI点信息 而且这些功能基本都长得差不多 所以网上查了下原来在SDK 文档里就有 在Dev Guide中有详细的介绍 不过都是英文的 看了好久呢

功能是比较简单的 就是配置起来有点麻烦 下面详细说一下

首先看效果

  

就这样简单 首先来看配置:

一、搜索框配置文件 是一个用来配置您的应用程序中搜索框的设置的XML文件,这个文件一般命名为searchable.xml,并且保存在项目的res/xml/目录下。 配置文件的根节点必须为searchable,可以有一个或多个属性。

可以发现在SearchableInfo中 android是通过com.android.internal.R.styleable.Searchable 这个ID来获取这个配置文件的

这个Searchable应该就是标签的名字,所以必须这么命名,至于文件名不重要了 文档中说must be saved in the res/xml/ project directory 也就这个文件名不重要 但这个文件必须放在XML目录下 位置确定了 内容大该就是

<?xml version="1.0" encoding="utf-8"?> 
<searchable xmlns:android="
http://schemas.android.com/apk/res/android
    android:label="@string/searchLabel"

    android:hint="@string/searchHint" 
    android:icon="@drawable/menu_route"   

    android:searchSuggestAuthority="com.debby.googlemap.SuggestionProvider"  
    android:queryAfterZeroResults="false"

    android:searchSuggestSelection=" ? "> 
</searchable> 

其中有个 android:icon="@drawable/menu_route" 本来以为可以设置 搜索Text前面那个View的 后来发现不起作用,而且文档中都没提到这个属性 看来确实没用啊 因为这属性我可折腾好久 这个以后再说吧

还有一点要注意的就是:  android:label android:hint 属性不能直接写值 而是要points to a string resource 就是用配置在values里的 

android:label 标签不知道有啥用 不过还要有  android:hint 就是TextView为空的时候显示的值 相当于提示信息了

基本配置就这些 还有大量的配置是语音搜索的,不过估计这个功能真是不怎么常用吧 想要研究的就看文档吧 挺详细的 先看看吧

    <?xml version="1.0" encoding="utf-8"?>
    <searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="string resource"
        android:hint="string resource"
        android:searchMode=["queryRewriteFromData" | "queryRewriteFromText"]
        android:searchButtonText="string resource"
        android:inputType="inputType"
        android:imeOptions="imeOptions"
        android:searchSuggestAuthority="string"
        android:searchSuggestPath="string"
        android:searchSuggestSelection="string"
        android:searchSuggestIntentAction="string"
        android:searchSuggestIntentData="string"
        android:searchSuggestThreshold="int"
        android:includeInGlobalSearch=["true" | "false"]
        android:searchSettingsDescription="string resource"
        android:queryAfterZeroResults=["true" | "false"]
        android:voiceSearchMode=["showVoiceSearchButton" | "launchWebSearch" | "launchRecognizer"]
        android:voiceLanguageModel=["free-form" | "web_search"]
        android:voicePromptText="string resource"
        android:voiceLanguage="string"
        android:voiceMaxResults="int"
        >
        <actionkey
            android:keycode="KEYCODE"
            android:queryActionMsg="string"
            android:suggestActionMsg="string"
            android:suggestActionMsgColumn="string" >
    </searchable>


二、创建一个搜索功能的Activity

     这里的Activity可以新建一个 当然也可以是当前弹出搜索框的Acitvity  这里我用到的MapAcitivity就是要显示搜索结果的 所以这里就直接用这个Acitivity了

     那这两种方式实现差不多 不过也有点小小的差别 下面来看:

   首先配置是一样的 就是在Acitivity 标签中加入:             
         <intent-filter> 
             <action android:name="android.intent.action.SEARCH" /> 
         </intent-filter> 
         <meta-data android:name="android.app.searchable" 
                    android:resource="@xml/searchable"/> 

就可以了。那这样的配置也就是只在这个Activity中可以使用搜索功能,其实Android的搜索框可以支持整个应用Application的。

这样就需要创建一个专门处理搜索的Acitivity 可以这样配置 需要在<application></application> 这个标签下的

    <!-- declare the default searchable Activity for the whole app -->
    <meta-data android:name="android.app.default_searchable"
               android:value=".MySearchableActivity" />
 

三、调用搜索框 现在已经配置完成了 下面就可以开始调用了

调用的方法很简单 所有的Acitivity都可以调用onSearchRequested() 方法 这样搜索框就出现了 ,那测试的时候可以有个简单的方法

在onCreate()方法中调用setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL),这样,当用户按下键盘上的按键时,将会自动激活搜索框

如果你要在执行搜索时,进行别的操作,可以重写onSearchRequested()方法 如下:

    @Override
    public boolean onSearchRequested() {
       //这个方法中干你想干的事
       doSometingOther();
       return super.onSearchRequested();
    }

还有如果我们想在调用的时候传递一些参数 也是可以的

   public boolean onSearchRequested() {
     Log.i(TAG,"onSearchRequested------------========"); 
     Bundle appData = new Bundle();
        appData.putString("key", "your info");
        startSearch(null, true, appData, false); 
        return true;
    }

四、接受查询条件 并执行查询

如果是创建了专门处理查询的Acitivity 当然可以直接在onCreate中 执行查询操作

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search);
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
}

但如果是在当前的Acitivity上这样就不行了 因为onCreate就执行一次 这样就可以通过onNewIntent来实现了

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search);
    handleIntent(getIntent());
}
 
@Override
protected void onNewIntent(Intent intent) {
    setIntent(intent);
    handleIntent(intent);
}
 
private void handleIntent(Intent intent) {
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
}

这样就会通过doMySearch()完成了查询操作了 不过还有点需要注意 查询完成后我按返回发现还是这个Acitivity 不过是查询前的

这说明在Activity栈里有两个我的这个MapAcitivity实例 这个可以通过在Acitivity里android:launchMode=”singleTop”这样的配置解决

我的Acitivity配置是这样的 
        <activity

            android:name=".GoogleMapActivity"

            android:launchMode="singleTop"
            android:label="@string/app_name">
            <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.SEARCH" /> 
            </intent-filter> 
            <meta-data android:name="android.app.searchable" 
                    android:resource="@xml/searchable"/> 
        </activity>

五、纪录历史关键字

我们在查询完成后会希望保存这次查询的条件 甚至有的会连结果都保存了

 android这里实现了保存关键字的功能 是通过SearchRecentSuggestionsProvider 来实现的

首先创建一个Provider类

public class SearchSuggestionProvider extends SearchRecentSuggestionsProvider {
   
    final static String AUTHORITY = "com.debby.googlemap.SuggestionProvider";
   
    final static int MODE = DATABASE_MODE_QUERIES;
    public SearchSuggestionProvider() {
        super();
        setupSuggestions(AUTHORITY, MODE);
    }
}

当然还要在 Manifest中配置
   <provider android:name="com.debby.googlemap.SearchSuggestionProvider"
            android:authorities="com.debby.googlemap.SuggestionProvider" />

这里注意 android:authorities 的配置与Provider里的保持一致就好了

这样在Acitivity里就可以调用了

       SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
       suggestions.saveRecentQuery(query, null);

保存完成了 点击搜索完成后保存成功了 下次搜索就可以看到 效果看PP

 

那有些时候需要保存一些查询结果 例如我在地图上查询一个地点位置 那我下次查询的时候希望可以快速实现查询


这种情况就可以把上次查询的一些该地点的信息 譬如 经纬度等信息保存下来 这样就直接通过sqlit来手动保存数据

可以在handleIntent()方法中进行插入 查询操作来完成了 就是个数据库操作 不再详细实现了




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值