如果需要在Android開機(jī)時(shí)自動啟動應(yīng)用程序,可以通過響應(yīng)android.intent.action.BOOT_COMPLETED廣播消息來實(shí)現(xiàn), Android系統(tǒng)啟動結(jié)束時(shí),會發(fā)出 android.intent.action.BOOT_COMPLETED 消息。 具體步驟如下:
弓長嶺網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),弓長嶺網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為弓長嶺近千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個(gè)售后服務(wù)好的弓長嶺做網(wǎng)站的公司定做!
1. 定義一個(gè)Broadcast Receiver ,比如:BootupReceiver
[java]
public class BootupReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//better delay some time.
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent i = new Intent(context, BootupDemoActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
android程序強(qiáng)行關(guān)閉后,讓程序自動啟動的方法為:
1、自己建一個(gè)service,不斷的去判斷,如果Activity掛掉了,就在service里啟動它。
2、在程序里面寫個(gè)廣播什么的到程序里面 ,比如 一些apk程序。一檢測到wifi開啟,廣播就激發(fā),啟動程序。
article class="_2rhmJa"
Android 設(shè)備開機(jī)自啟動的可以用廣播實(shí)現(xiàn),因?yàn)?Android 設(shè)備開機(jī)時(shí)會發(fā)送一條開機(jī)廣播 "android.intent.action.BOOT_COMPLETED"。接收后實(shí)現(xiàn)啟動就完成了。
接下來是準(zhǔn)備工作
如果按照上面的全部步驟后操作后,重啟沒有自動啟動程序,怎么辦呢?是怎么回事呢?
*那么首先請檢查一下你的手機(jī)是不是安裝了360等安全助手之類的軟件,如果有,請?jiān)谲浖淖詥榆浖芾碇袑pp設(shè)置為允許
*我的手機(jī)沒有安裝這些軟件,但是手機(jī)中自帶了安全助手,有的手機(jī)系統(tǒng)設(shè)置里面自帶了自啟動軟件管理的功能 ,所以在這里將我們的app設(shè)置為允許開機(jī)啟動),重啟手機(jī),測試是否成功。
然而并沒有成功
接收不到BOOT_COMPLETED廣播可能的原因
(1)、BOOT_COMPLETED對應(yīng)的action和uses-permission沒有一起添加
(2)、應(yīng)用安裝到了sd卡內(nèi),安裝在sd卡內(nèi)的應(yīng)用是收不到BOOT_COMPLETED廣播的
(3)、系統(tǒng)開啟了Fast Boot模式,這種模式下系統(tǒng)啟動并不會發(fā)送BOOT_COMPLETED廣播
(4)、應(yīng)用程序安裝后重來沒有啟動過,這種情況下應(yīng)用程序接收不到任何廣播,包括BOOT_COMPLETED、ACTION_PACKAGE_ADDED、CONNECTIVITY_ACTION等等。
Android3.1之后,系統(tǒng)為了加強(qiáng)了安全性控制,應(yīng)用程序安裝后或是(設(shè)置)應(yīng)用管理中被強(qiáng)制關(guān)閉后處于stopped狀態(tài),在這種狀態(tài)下接收不到任何廣播,除非廣播帶有FLAG_INCLUDE_STOPPED_PACKAGES標(biāo)志,而默認(rèn)所有系統(tǒng)廣播都是FLAG_EXCLUDE_STOPPED_PACKAGES的,所以就沒法通過系統(tǒng)廣播自啟動了。所以Android3.1之后
(1)、應(yīng)用程序無法在安裝后自己啟動
(2)、沒有ui的程序必須通過其他應(yīng)用激活才能啟動,如它的Activity、Service、Content Provider被其他應(yīng)用調(diào)用。
存在一種例外,就是應(yīng)用程序被adb push you.apk /system/app/下是會自動啟動的,不處于stopped狀態(tài)。
并不太懂 我的APP啟動后 已經(jīng)收到廣播
第一種方式 我再模擬器上 測試 可以 android 9.0版本
桌面設(shè)置也會把你的app當(dāng)成一個(gè)桌面主題,還有一個(gè)選項(xiàng)是系統(tǒng)桌面,你需要設(shè)置成自己的app
如果找不到桌面設(shè)置選項(xiàng),可以從手機(jī)設(shè)置–應(yīng)用程序-查看所有應(yīng)用程序(包括系統(tǒng)的應(yīng)用程序),找到桌面程序之類的字眼的應(yīng)用,清楚其默認(rèn)設(shè)置。
AMS主要功能:
AMS是Android中最核心的服務(wù),主要負(fù)責(zé)系統(tǒng)中四大組件的啟動、切換、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等工作。還負(fù)責(zé)啟動或殺死應(yīng)用程序的進(jìn)程。
WMS主要功能:
為所有窗口分配Surface。
管理Surface的顯示順序、尺寸、位置。
管理窗口動畫。
輸入系統(tǒng)相關(guān):WMS是派發(fā)系統(tǒng)按鍵和觸摸消息的最佳人選,當(dāng)接收到一個(gè)觸摸事件,它需要尋找一個(gè)最合適的窗口來處理消息。
PWS主要功能:
PMS 用來管理跟蹤所有應(yīng)用APK,包括安裝,卸載,解析,控制權(quán)限等。
SystemServer也是一個(gè)進(jìn)程,包括AMS、PMS、WMS等等。
zygote意為“受精卵“。Android是基于Linux系統(tǒng)的,而在Linux中,所有的進(jìn)程都是由init進(jìn)程直接或者是間接fork出來的,zygote進(jìn)程也不例外。
App進(jìn)程是用戶點(diǎn)擊桌面icon時(shí),通過Launcher進(jìn)程請求SystemServer,再調(diào)用Zygote孵化的。
①點(diǎn)擊啟動一個(gè)App,Launcher進(jìn)程采用Binder IPC向ActivityManagerService發(fā)起startActivity請求;
②ActivityManagerService接收到請求后,向zygote進(jìn)程發(fā)送創(chuàng)建進(jìn)程的請求;
③Zygote進(jìn)程fork出新的子進(jìn)程,即App進(jìn)程;
④App進(jìn)程通過Binder IPC向sytem_server進(jìn)程發(fā)起綁定Application請求;
⑤system_server進(jìn)程在收到請求后,進(jìn)行一系列準(zhǔn)備工作后,再通過binder IPC向App進(jìn)程發(fā)送scheduleLaunchActivity請求;
⑥App進(jìn)程的binder線程(ApplicationThread)在收到請求后,通過handler向主線程發(fā)送LAUNCH_ACTIVITY消息;
⑦主線程在收到Message后,通過發(fā)射機(jī)制創(chuàng)建目標(biāo)Activity,并回調(diào)Activity.onCreate()等方法。
⑧到此,App便正式啟動,開始進(jìn)入Activity生命周期,執(zhí)行完onCreate/onStart/onResume方法,UI渲染結(jié)束后便可以看到App的主界面。
備注:
Launcher,PMS,Zygote,App進(jìn)程是三個(gè)獨(dú)立的進(jìn)程,相互通信就需要使用進(jìn)程間通信機(jī)制。與Zygote通信是使用的socket通信,Launcher,PMS,App進(jìn)程間使用的是Binder機(jī)制。
翻譯自:
這篇文章講解當(dāng)用戶點(diǎn)擊應(yīng)用圖標(biāo)時(shí),安卓如何啟動你的應(yīng)用。安卓系統(tǒng)做了很多幕后工作,來使得你的launch activity對用戶可見。本文通過重要階段的講解和調(diào)用序列詳細(xì)講解這一過程。
安卓應(yīng)用在這兩個(gè)方面是獨(dú)特的:
多個(gè)入口點(diǎn) :Android應(yīng)用程序由不同的組件組成,它們可以調(diào)用其他應(yīng)用程序擁有的組件。這些組件大致對應(yīng)于任何應(yīng)用程序的多個(gè)入口點(diǎn)。因此,它們不同于具有像main()方法那樣的單個(gè)入口點(diǎn)的傳統(tǒng)應(yīng)用程序。
擁有自己的小世界 :每個(gè)Android應(yīng)用程序都生活在自己的世界中,它在單獨(dú)的進(jìn)程中運(yùn)行,擁有自己的Dalvik VM實(shí)例,并分配有唯一的用戶ID。
必要時(shí)會啟動Android進(jìn)程。
每當(dāng)用戶或其他系統(tǒng)組件請求執(zhí)行屬于您應(yīng)用程序的組件(可能是服務(wù),活動或意圖接收器)時(shí),Android系統(tǒng)都會為您的應(yīng)用程序啟動一個(gè)新進(jìn)程(如果尚未運(yùn)行)。通常,進(jìn)程一直運(yùn)行直到被系統(tǒng)殺死。應(yīng)用程序流程是按需創(chuàng)建的,在您看到應(yīng)用程序的啟動活動啟動并運(yùn)行之前,發(fā)生了許多事情。
每個(gè)應(yīng)用程序都在其自己的進(jìn)程中運(yùn)行 :默認(rèn)情況下,每個(gè)Android應(yīng)用程序都在其自己的Android進(jìn)程中運(yùn)行,而這個(gè)進(jìn)程只不過是一個(gè)Linux進(jìn)程,而該進(jìn)程首先需要一個(gè)執(zhí)行線程。例如,當(dāng)您單擊電子郵件中的超鏈接時(shí),網(wǎng)頁將在瀏覽器窗口中打開。您的郵件客戶端和瀏覽器是兩個(gè)單獨(dú)的應(yīng)用程序,它們分別在兩個(gè)單獨(dú)的進(jìn)程中運(yùn)行。click事件使Android平臺啟動新進(jìn)程,以便它可以在其自身進(jìn)程的上下文中實(shí)例化瀏覽器活動。這對于應(yīng)用程序中的任何其他組件同樣適用。
讓我們退后一會兒,快速瀏覽一下系統(tǒng)啟動過程。與大多數(shù)基于Linux的系統(tǒng)一樣,啟動加載程序在啟動時(shí)將加載內(nèi)核并啟動init進(jìn)程。然后,init會生成稱為“守護(hù)程序”的低級Linux進(jìn)程,例如android debug守護(hù)程序,USB守護(hù)程序等。這些守護(hù)程序通常處理低級硬件接口,包括無線電接口。
然后,初始化過程會啟動一個(gè)非常有趣的過程,稱為“zygote'。
顧名思義,這是其余Android應(yīng)用程序的開始。這是初始化Dalvik虛擬機(jī)的第一個(gè)實(shí)例的過程。它還預(yù)加載Android應(yīng)用程序框架和系統(tǒng)上安裝的各種應(yīng)用程序使用的所有常見類。因此,它準(zhǔn)備進(jìn)行復(fù)制。它統(tǒng)計(jì)偵聽套接字接口上的將來請求,以產(chǎn)生新的虛擬機(jī)(VM)來管理新的應(yīng)用程序進(jìn)程。收到新請求后,它會分叉以創(chuàng)建一個(gè)新進(jìn)程,該進(jìn)程將獲取預(yù)先初始化的VM實(shí)例。
zygote之后,init啟動運(yùn)行時(shí)過程。
然后zygote分叉以啟動一個(gè)名為System server的托管良好的進(jìn)程。系統(tǒng)服務(wù)器在其自己的上下文中啟動所有核心平臺服務(wù),例如活動管理器服務(wù)和硬件服務(wù)。
此時(shí),完整的堆棧已準(zhǔn)備就緒,可以啟動第一個(gè)應(yīng)用程序流程-主頁應(yīng)用程序,該應(yīng)用程序顯示主屏幕(也稱為啟動器應(yīng)用程序)。
click事件被轉(zhuǎn)換為 startActivity(intent), 并通過Binder IPC路由到 ActivityManagerService 。ActvityManagerService執(zhí)行多個(gè)步驟
如您所見,當(dāng)用戶單擊圖標(biāo)并啟動新應(yīng)用程序時(shí),許多事情發(fā)生在幕后。這是全圖:
流程創(chuàng)建:
ActivityManagerService 通過調(diào)用 startProcessLocked() 方法創(chuàng)建一個(gè)新進(jìn)程,該方法通過套接字連接將參數(shù)發(fā)送到Zygote進(jìn)程。Zygote派生自己并調(diào)用 ZygoteInit.main() ,然后實(shí)例化 ActivityThread 對象并返回新創(chuàng)建的進(jìn)程的進(jìn)程ID。
默認(rèn)情況下,每個(gè)進(jìn)程都有一個(gè)線程。主線程有一個(gè) Looper 實(shí)例來處理來自消息隊(duì)列的消息,并且它在 run() 方法的每次迭代中都調(diào)用 Looper.loop() 。 Looper 的工作是從消息隊(duì)列中彈出消息并調(diào)用相應(yīng)的方法來處理它們。然后,ActivityThread通過隨后調(diào)用 Looper.prepareLoop() 和 Looper.loop()來 啟動消息循環(huán)。
以下序列詳細(xì)捕獲了調(diào)用序列:
figcaption class="jv jw di dg dh jx jy bo b fc cp ga" data-selectable-paragraph="" style="box-sizing: inherit; font-weight: 400; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 20px; margin-left: auto; margin-right: auto; max-width: 728px; font-size: 14px; color: rgb(117, 117, 117); margin-top: 10px; text-align: center;"Android應(yīng)用啟動:單擊事件以執(zhí)行Looper調(diào)用順序/figcaption
應(yīng)用程序綁定:
下一步是將此新創(chuàng)建的過程附加到特定應(yīng)用程序。這是通過在線程對象上調(diào)用 bindApplication() 來完成的。此方法將 BIND_APPLICATION 消息發(fā)送到消息隊(duì)列。該消息由 Handler 對象檢索,該對象隨后調(diào)用 handleMessage() 方法以觸發(fā)特定于消息的操作 -handleBindApplication() 。此方法調(diào)用 makeApplication() 方法,該方法將應(yīng)用程序特定的類加載到內(nèi)存中。
下圖描述了該調(diào)用序列。
figcaption class="jv jw di dg dh jx jy bo b fc cp ga" data-selectable-paragraph="" style="box-sizing: inherit; font-weight: 400; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 20px; margin-left: auto; margin-right: auto; max-width: 728px; font-size: 14px; color: rgb(117, 117, 117); margin-top: 10px; text-align: center;"Android應(yīng)用啟動:BIND_APPLICATION消息處理/figcaption
啟動活動:
在上一步之后,系統(tǒng)包含負(fù)責(zé)應(yīng)用程序的進(jìn)程,并將應(yīng)用程序類加載到進(jìn)程的私有內(nèi)存中。在新創(chuàng)建的流程和現(xiàn)有流程之間,啟動活動的調(diào)用順序很常見。
實(shí)際的啟動過程從 realStartActivity() 方法開始, 該 方法在應(yīng)用程序線程對象上調(diào)用 sheduleLaunchActivity() 。此方法將 LAUNCH_ACTIVITY 消息發(fā)送到消息隊(duì)列。該消息由 handleLaunchActivity() 方法處理,如下所示。
假設(shè)用戶單擊“視頻瀏覽器”應(yīng)用程序。啟動該活動的調(diào)用順序如圖所示。
figcaption class="jv jw di dg dh jx jy bo b fc cp ga" data-selectable-paragraph="" style="box-sizing: inherit; font-weight: 400; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 20px; margin-left: auto; margin-right: auto; max-width: 728px; font-size: 14px; color: rgb(117, 117, 117); margin-top: 10px; text-align: center;"Android應(yīng)用啟動: LAUNCH_ACTIVITY消息處理 /figcaption
該活動通過 onCreate() 方法調(diào)用開始其托管生命周期。該活動通過 onRestart() 調(diào)用進(jìn)入前臺,并通過 onStart() 調(diào)用開始與用戶進(jìn)行交互。
安裝自啟動:
要做這個(gè)功能有一個(gè)前提,那就是用戶的機(jī)器上已經(jīng)裝過相應(yīng)應(yīng)用,也就是說只有升級APK的時(shí)候才可以這么干,因?yàn)橐獔?zhí)行的功能需要程序的配合。
具體步驟如下:
首先要知道程序已經(jīng)安裝完成,所以需要在程序中注冊一個(gè)廣播監(jiān)聽(必須是靜態(tài)的,你懂的)apk安裝完成的action:"android.intent.action.PACKAGE_ADDED",在這個(gè)廣播的onReceive方法中監(jiān)聽action,并通過intent.getDataString()方法判斷安裝程序的包名是否屬于自己的包名,如果是做下一步操作;
通過Intent顯式或者隱式的啟動你自己的程序。
建議:
??最好不要這樣干,你要考慮一下用戶的感受,特別是那種自動安裝不需要點(diǎn)確認(rèn)的時(shí)候,正在玩游戲、看視頻、看小說、用微信你自動打開一個(gè)應(yīng)用
開機(jī)自啟動
android實(shí)現(xiàn)開機(jī)自啟動可能是移動操作系統(tǒng)中最簡單的了,只需要監(jiān)聽一個(gè)開機(jī)啟動的Broadcast(廣播)即可。首先寫一個(gè)Receiver(即廣播監(jiān)聽器),繼承BroadcastReceiver。
如下所示:
public class BootReceiver extends BroadcastReceiver {
private PendingIntent mAlarmSender;
@Override
public void onReceive(Context context, Intent intent) {
// 在這里干你想干的事(啟動一個(gè)Service,Activity等),本例是啟動一個(gè)定時(shí)調(diào)度程序,每30分鐘啟動一個(gè)Service去更新數(shù)據(jù)
mAlarmSender = PendingIntent.getService(context, 0, new Intent(context,
RefreshDataService.class), 0);
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager) context
.getSystemService(Activity.ALARM_SERVICE);
am.cancel(mAlarmSender);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
30 * 60 * 1000, mAlarmSender);
}
}
接下來,只需要在應(yīng)用程序配置文件AndroidManifest.xml中注冊這個(gè)Receiver來監(jiān)聽系統(tǒng)啟動事件即可
如下所示:
receiver android:name=".service.BootReceiver"
intent-filter
!-- 系統(tǒng)啟動完成后會調(diào)用--
action android:name="android.intent.action.BOOT_COMPLETED"
/action
/intent-filter
/receiver