国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android跨應用啟動實例詳解

2019-12-12 03:00:51
字體:
來源:轉載
供稿:網友

Android跨應用啟動

前言:

相信大家,很多時候都是在自己的應用中,啟動自己寫的Activity,Service、BroadcastReceiver、contentProvider 。換句話說,這些都只是 * 單個應用中 組件間 * 的啟動。而我們下面要談論的是 兩個應用間 組件 的啟動。即――使用 隱式Intent方式 啟動應用B的某個組件。

一、在開始之前,先來梳理一下跨應用啟動的2種方式:

第一種:在Activity中,啟動另一個app的組件。

第二種:在Service中,啟動另一個app的組件。

從所周知,Android中有四大組件,那么為什么小編,只介紹Activity和Service中啟動另一個應用的四大組件?

其實,BroadcastReceiver組件也是可以啟動 4大組件的。這是因為onReceive()方法中會要求傳入context實例,有了context實例,就能使用context的方法,啟動其他組件。

至于contentProvider,我想大家還沒見過,這娃自動去干過事情吧,都是被動的調用。

所以在寫代碼的時候,我們經常會在Activity或者Service中去啟動一個組件,BroadcastReceiver很少,而contentProvider更是沒見過。

另外需要跟大家說一下,Context類是一個抽象類,傳入的context實例是由其子類來實現的,這種――用父類聲明變量,由子類來實現的思維方式,在Java中是很常見的。特別是接口和抽象類,經常用到這種方式。對于小編這種由C轉Java的人來說,真是一大坑啊。

為什么Activity和Service都可以直接使用圖中的四個方法呢,這是因為Activity和Service都是繼承自ContextWrapper,所以子類擁有父類的方法。BroadcastReceiver和contentProvider則不是,具體大家可以看官方API。

二、跨應用啟動的實戰

** 下面讓我們正式進入今天的主題:跨應用啟動實戰**

1:AppA的Activity中,啟動AppB的Activity

Android提供了在一個App中啟動另一個App中的Activity的能力,這使我們的程序很容易就可以調用其他程序的功能,從而就豐富了我們App的功能。比如在微信中發送一個位置信息,對方可以點擊這個位置信息啟動騰訊地圖并導航。這個場景在現實中作用很大,尤其是朋友在陌生的環境找不到對方時,這個功能簡直就是救星。

本來想把本文的名字叫啟動另一個進程中的Activity,覺得這樣才有逼格。因為每個App都會運行在自己的虛擬機中,每個虛擬機跑在一個進程中。但仔細一想,能夠稱為一個進程,前提是這個App必須要運行起來才行。而Android提供的能力,是不需要另一個App啟動就可以將其特定的Activity啟動起來的。

也就是說B應用是處理未啟動的狀態,也就是還沒有成為系統的一個進程,那么當使用A啟動B應用的某個組件時,請問,B應用是否成為系統的進程?答案是yes。怎么看呢,可以從Android Studio 的Android device monito 中結合虛擬機看。

我們有至少兩種辦法達到啟動另一個App中的Activity。

第一種―――隱式Intent的action方式。

相信這種方式,大家都不會陌生。這里就不進行過多的解析。這里只貼一下AppB的manifest(文件清單):

從文件清單中,我們可以看到,appB中有兩個Activity。其中SecondActivity就是要被appA啟動的Activity。
那么我們只要在appA的任意一個組件(Activity或Service),做如下的調用:

Intent intent=new Intent("android.intent.action.SecondActivity");startActivity(intent);

就可以成功在 A應用中 啟動B應用的 組件。另外還要跟大家說一點,SecondActivity的category一定要在文件清單中添加上,否則啟動的時候會報錯的。

不知道大家有沒有思考過這三個事情: 1、當A應用 啟動 B應用的SecondActivity,那么B應用的MainActivity會不會被啟動呢?正常情況下,我們點擊應用B,進到的是MainActivity這個活動,那么現在我們是通過跨應用啟動,會不會要經過B的MainActivity呢?答案是不會。2、當我們在SecondActivity中點擊Back回退鍵時,回到的是A應用的mainActivity界面,這里時候大家有沒有想過。 SecondActivity和appA的mainActivity是不是同處于一個棧中呢?這時候就要去打印棧的ID了。3、由上面的兩件事,不知道大家想起:Android對于Activity的管理,也就是framework層的ActivityManager。也就是說,你手機上的N多應用,當你打開某一個應用是,這個應用的Activity都是由ActivityManager這娃來創建和管理的。應用本身并沒有創建Activity的能力。當然這其中又涉及到了Ibinder的通訊。這里暫時不講。
 

第二種用intent設置className或component的辦法啟動。舉例如下。

新建兩個項目ProjectA和ProjectB,用B中的MainActivity啟動A的MainActivitity。關鍵代碼如下:

ProjectA MainActivity

@Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); String packageName = "com.example.mylife.anotherapp"; String className = "com.example.mylife.anotherapp.MainActivity"; intent.setClassName(packageName, className); //second method //intent.setComponent(new ComponentName("com.example.mylife.anotherapp","com.example.mylife.anotherapp.MainActivity")); Bundle bundle = new Bundle(); bundle.putString("msg", "this message is from project B "); intent.putExtras(bundle); intent.putExtra("pid", android.os.Process.myPid()); startActivityForResult(intent, 1); //startActivity(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case 1: if(resultCode == RESULT_OK) { textView.setText(data.getStringExtra("result")); } break; } }

ProjectB MainActivity

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.text); Intent intent = getIntent(); if(intent != null) { textView.setText(intent.getStringExtra("msg")); } } public void OnClick(View view) { Intent intent = new Intent(); intent.putExtra("result","OK! from project a."); this.setResult(RESULT_OK,intent); this.finish();//要清楚這里為什么要用finish()。 }

注意:如果在應用B中,是通過按下Back鍵,回退到應用A的MainActivity活動,那么A的onActivityResult()方法是不會被回調的,這是因為ProjectB的MainActivity活動只是出棧而已,并沒有銷毀。而只有ProjectB的MainActivity活動被銷毀的時候,才會回調A的onActivityResult()方法。那如果是按了Back鍵回退的話怎么處理呢?這時候只要重寫appB的onBackPressed()方法就好了。

@Overridepublic void onBackPressed() { super.onBackPressed(); Intent intent = new Intent(); intent.putExtra("result","OK! from project a."); this.setResult(RESULT_OK,intent); this.finish();//要清楚這里為什么要用finish()。}

二:進階―――在A應用的Activity中啟動(停止)――B應用的服務

應用B的manifest

應用B的service的代碼:

public class MyService extends Service { private static final String TAG = "MyService"; public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public int onStartCommand(Intent intent,int flags, int startId) { Log.d(TAG, "onStartCommand: "); if(intent != null) { Log.d(TAG, "onStartCommand: "+intent.getStringExtra("msg")); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: "); } }

應用A的代碼:

@Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); String packageName = "com.example.mylife.anotherapp"; String className = "com.example.mylife.anotherapp.MyService"; intent.setClassName(packageName, className); switch (v.getId()) { case R.id.btn_start: Bundle bundle = new Bundle(); bundle.putString("msg", "this message is from project B "); intent.putExtras(bundle); intent.putExtra("pid", android.os.Process.myPid()); startService(intent); break; case R.id.btn_stop: stopService(intent); break; } }

測試結果:A應用直接啟動B應用的服務,而B應用并不會打開自己的Activity。

本次代碼參考://m.survivalescaperooms.com/article/111896.htm

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 于都县| 贵港市| 瑞金市| 寻甸| 呼伦贝尔市| 博野县| 静宁县| 汤阴县| 万安县| 宜良县| 通州市| 乾安县| 富阳市| 桐庐县| 武胜县| 宁都县| 都安| 临洮县| 上栗县| 扶绥县| 海城市| 嵩明县| 德庆县| 合作市| 靖远县| 义马市| 肇庆市| 增城市| 灵武市| 乐业县| 诏安县| 龙南县| 满洲里市| 景东| 称多县| 馆陶县| 盱眙县| 天门市| 阳朔县| 分宜县| 顺义区|