知識社群登入
位置: 艾鍗學院 Blog > 專業論壇 > 討論
Android 應用程式管理
1樓
Jarey老師
我想請問您,當我寫了一支SERVICE程式沒有UI只在背景執行,因此這支SERVICE只能在"執行的服務"選單中看見及停止,但是雖然程式沒有UI,還是可以在"管理應用程式"中看見,請問老師有可能在"管理應用程式"中隱藏這支程式的名稱嗎?
另外,請問在安裝完程式及SERVICE後,可能將程式移除卻讓SERVICE繼續執行嗎?
謝謝
2樓
應用程式管理集就像是你在windows 作業系統裡按下contrl alt. delete. 中的程序管理員.
用戶可以從中去關閉不想要執行的應用程式,所以是無法隱藏的, 如果你不想讓用戶看出來
你有跑背景程式,那你可以在services名稱還有圖示上做手腳,讓用戶看起來這是隻android系
統服務程式,就不會隨便去關掉. 但還是不建議如此做.

另外程式一但移除後,除了寫入到sd卡中的資料可能還會留著之外(因有些軟體連sd的內容也
會主動清掉,例如kkbox下載的音樂). 其它與此程式相關的應用程式資料都會被清掉,自然services
也不會執行了. 因為如果今天有一個惡意軟體在背景跑惡意程式去收集你個資.而就算你刪除
了軟體.在背景跑的惡意程式還關不掉,那就會有安全性的關題.
3樓
老師謝謝您的回答
這邊再問一個問題,我利用Broadcastreceiver及service練習寫了一個手機開機自動執行的service程式,主要在檢視開機執行及服務的生命週期,我發現因為成是沒有activity所以不會出現在所有程式列表中(也就是Home選單中沒有圖示)且亦不會出現在最近開啟的程式,目前觀察到在管理應用程式及正在執行的服務中有出現,可是在管理應用程式列表中顯示的位置並不是位於"正在執行"而是"已下載",感覺比較像是WINDOWS的"新增移除程式",我比較好奇的是,Android除了原生服務外,無法自行撰寫開機執行的常駐服務嗎?(因為我可以看到我撰寫的服務內容註明由哪一支程式啟動,原生服務則沒有,請問有辦法或技術可以在服務安裝執行後,僅出現於"正在執行的服務"列表中,顯示資訊與原生服務相同且在"已下載"列表無紀錄)
 
謝謝
4樓
Hi Terry:

Android是可以撰寫完全沒有Activity.僅有Services在背景跑的應用程式,而該應用程式可以透過BroadCastReceiver
來啟動。若要在開機時就啟動則需要接收android.intent.action.BOOT_COMPLETED 這個廣播,該廣播會在開機時由
系統發送出來,另外我建議你可以在多聽一個廣播android.intent.action.USER_PRESENT ,這個擴播會在當用戶將
手機解鎖時發出,這將可以更將確保你的services就算被關掉了,只要當用戶下次在做解鎖動作時在再次被自動啟動。
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)
|| intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.i("BootServices", "Receiver Action: Boot Completed");
Intent i = new Intent(context, BootServices.class);
context.startService(i);

Log.i("BootServices", " service has started!");
}

}
基本上接收到BOOT_COMPLETED後利用Intent啟動Services後,該Services就會出現在應用程式管理列表的執行
中的List中, 至於你提到說你看不到應用程式出現在執行中的LIst,依我判斷很有可能是你忘了將該Services註冊
到AndroidManifest.xml 之中。 所以系統就不會自動跑起你的Services(因為不認得),你可以在試看看,若還有
問題,我在將我寫的這個小範例程式寄給你參考.

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <receiver android:name="BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
                <category android:name="android.intent.category.LAUNCHER"></category>
                <action android:name="android.intent.action.USER_PRESENT"></action>
            </intent-filter>
        </receiver>
        
        <service android:name="BootServices" android:label="BootServvicesTest"></service>

    </application>




BR.
Kyle.
5樓
補充一下: 剛提到的ACTION_USER_PRESENT
算是一招很強制用戶跑Services的方式,就算用戶進去應用程式管理員把該Services關掉了,
只要手機一關營幕在重開解鎖,該services就又會自動在被跑起來。或是當用戶的系統記憶
體快不足了,你的背景services可以被系統關掉了,同樣的只要用戶在一解鎖手機開畫面
你的services又可以再度的復活起來。 一般可以在搭配Service.setForeground(),可以
該你的services活更不容易因記憶體不足而被選中關閉.
6樓
Jarey老師
謝謝您快速且不厭其煩的回答,android.intent.action.USER_PRESENT 真是厲害,又讓我多學到一高招了
另外,我的SERVICE有正常執行(我有加入AndroidManifest.xml),我說的沒執行是指應用程式本身,例如我的專案名稱是TEST,程式安裝執行後,TEST因為沒有ACTIVITY就不像一般程式出現在"正在執行"列表,反而出現在"已下載"列表,而SERVICE出現在"執行中的服務"列表,點選它可以看到是由TEST這支應用程式啟動的資訊,我是想設計專案,讓這支SERVICE執行後跟原生的SERVICE顯示的資訊一樣,或是直接由Android啟動(像是WINDOWS啟動一樣),這樣就可以將包含BroadcastReceiver這支程式解除安裝,但是SERVICE還是在開機或解除螢幕鎖定後可以執行
 
謝謝
 
7樓
可以大概了解一下你做這個專案的應用目的嗎? 基本上Services必須是要由Activity或是BroadcastReceiver去啟動它,而且你的Services本身也是包在APK裡的一部份,因此是不可能讓你把程式解除安裝後,Services還可以停留在你的手機裡,一但
你把你的APK解除安裝後,所有該APK的應用程式都會被停止且結束。 你想要達到像內建的軟體讓用戶刪也刪不掉的,那
就是要做成prebuild在手機裡的軟體,像中華電信會把Hami APP preBuild在手機裡一樣,但這必須你要有Root 權限,並
且是在打包Android OS時就將軟體種進去了。 

另外己下載列表代表的意思其實是你己安裝的軟體,所以專案出現在己下載列表是正常的,一但你把軟體移除了就會從己下
載列表消失,另外執行中列表與正在執行列表的函義是完全不同的,我大概說明一下觀念:

1.執行中列表
Android的Activity應用程式都有其生命週期,今天你跑一個遊戲打到一半突然想要去收個信,這時你會按下Home鈕,此時你的遊戲是進入onStop()狀態,整個應用程式的記憶體都還沒有被回收,但CPU己經不會在去處理遊戲的運算,而是改去處理收信軟體,等到你收完信你在執行該遊戲時,這時由於遊戲記憶體都還在,所以程式得以很快速的回復運作,CPU會接著在去處理遊戲的運算。 
這就是與iphone的多工做法是雷同的,用戶感覺上會是多工因為你的遊戲還是可以接續做,但是實際上只是把之前的軟體記憶體資料保留,讓你下次回去做時可以保持著原狀,但CPU本身是沒有在多工做事的。 像這種記憶體還存在著等著被切回去跑的應用程式,就會出現在執行中列表,而你的Test應用程式本根本沒有Activity,也不會有Activity運作到一半進入onStop()資料保存在背景的狀況,所以根本不會出現在執行中列表。


2.正在執行中列表
而Android之所以可以做到真正的多工,就是利用Services元件,這是連CPU都同時多工在運算的元件,也就是跑在背
景的services同時也可以取得CPU運算能力去做事情,像這類的services就是被分類在正在執行中列表。


所以以上可以得知執行中列表主要只會吃記憶體不會吃CPU和電源,主要是方便用戶下次回去執行該應用程式時,可以
快速的回復到用戶上次執行中的狀態,讓軟體運做的更順。 Services背景跑的應用程式是可以取得CPU的運算能力,
也就是背景的services是會吃電吃記憶體的,每隻services都是正在執行的狀態,因此才會被分類到正在執行列表中。


8樓
剛提到的執行中應用程式的概念只是基本的概念,若想要真正了解Android是如何去處理不同應用程式之間的切換應用
如何提升應用程式的操作暢流性與一致性的使用體驗,如何在記憶體與效能之間取得平衡點。

那你需要詳細的去了解一下Android Activity Task的概念,你可以參考以下資料先:
9樓
Tarey老師
再次感謝,問了那麼多問題,主要是想了解Android是否有跟Windows的服務一樣(因為想法還停留在windows),所以很多問題都是依windows方式還想的,感謝您不厭其煩的回答
10樓
Tarey老師你好
不知能否向您請教
在service類別中可以使用onKeyDown偵測音量鍵按下動作嗎?(KEYCODE_VOLUME_DOWN)
謝謝
Jimmy