Android中,關於service的啟動兩種方式描述不正確的是
碰到群友問的一個問題,說:關於service的啟動兩種方式描述不正確的是(如圖)? 當時看到這個問題有點糾結,糾結內容如下:
A 選項沒有疑問,官網就是這麼說的
B選項就是我所糾結的地方,這個呼叫者如果退出了,那麼如果在onDestroy()中呼叫了unbindService 方法的話,那麼服務是終止的,這個是可以肯定的;但是如果沒有呼叫unbindService()方法的情況下,服務會終止嗎?(下面我對這個疑問做了實驗)
C選項也沒有疑問,官網就是這麼說的(雖然onStart()方法已經被 onStartCommand()取代,但是 onStartCommand()方法依然會呼叫onStart()方法),所以說也算是正確的。
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
D選項明顯是錯誤的,錯誤的地方最後一句,用stopService() 方法是結束不了用bindService()方法啟動的服務的(下面我會順道給予證實)。
我寫了個一個簡單的測試程式:如下:
package com.example.servicestest; import java.util.List; import java.util.Timer; import java.util.TimerTask; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends ActionBarActivity { private TestService bindService = null; private Button mbtn, mBtn2; private Timer mTimer; private ActivityManager myAM; List<RunningServiceInfo> myList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtn2 = (Button) findViewById(R.id.button2); mBtn2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, TestService.class); //intent.putExtra("from", "ActivityA"); bindService(intent, conn, BIND_AUTO_CREATE); Log.d("TestServiceMain", "StartService -- onclick"); } }); mbtn = (Button) findViewById(R.id.button1); mbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, TestService.class); MainActivity.this.stopService(intent); Log.d("TestServiceMain", "StopService -- onclick"); } }); if (mTimer == null) { mTimer = new Timer(); } mTimer.schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub myAM = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); myList = myAM.getRunningServices(Integer.MAX_VALUE); if (myList.size() <= 0) { Log.d("TestServiceMain", "runing nothing "); } for (RunningServiceInfo service : myList) { if ("com.example.servicestest.TestService".equals(service.service.getClassName())) { Log.d("TestServiceMain", "runing !!!!!!!!!!!!!!!! " + service.service.getClassName()); } } Log.d("TestServiceMain", "runing runing "); } }, 1000, 1000); } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { TestService.LocalBind binder = (TestService.LocalBind) service; bindService = binder.getService(); } //client 和service連線意外丟失時,會呼叫該方法 @Override public void onServiceDisconnected(ComponentName name) { bindService = null; } }; protected void onDestroy() { Log.d("TestServiceMain", "MainActivity onDestroy()"); unbindService(conn); Log.d("TestServiceMain", "MainActivity unbindService()"); super.onDestroy(); }; }
service
package com.example.servicestest; import java.util.Timer; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class TestService extends Service { private final String TAG = "TestService"; private LocalBind localBind = new LocalBind(); private Timer mTimer; public class LocalBind extends Binder { public TestService getService() { return TestService.this; } } private final IBinder mBinder = new LocalBind(); @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.i(TAG, "onCreate~~~~~~~~~~"); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.i(TAG, "onBind~~~~~~~~~~~~"); return mBinder; } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Log.i(TAG, "onStart~~~~~~~~~~~~"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.i(TAG, "onStartCommand~~~~~~~~~~~~"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub Log.i(TAG, "onUnbind~~~~~~~~~~~~~~~~"); return super.onUnbind(intent); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.i(TAG, "onDestroy~~~~~~~~~~~"); } }
那麼先證實B選項的第一種情況:
在onDestroy()中呼叫了unbindService 方法的話,那麼服務是終止的。
日誌如下:
10-31 10:40:35.316: D/TestServiceMain(24971): runing runing
10-31 10:40:36.321: D/TestServiceMain(24971): runing runing
10-31 10:40:36.866: D/TestServiceMain(24971): StartService -- onclick
10-31 10:40:36.866: I/TestService(24971): onCreate~~~~~~~~~~
10-31 10:40:36.866: I/TestService(24971): onBind~~~~~~~~~~~~
10-31 10:40:37.316: D/TestServiceMain(24971): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:40:37.316: D/TestServiceMain(24971): runing runing
10-31 10:40:38.316: D/TestServiceMain(24971): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:40:38.316: D/TestServiceMain(24971): runing runing
10-31 10:40:39.316: D/TestServiceMain(24971): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:40:39.316: D/TestServiceMain(24971): runing runing
10-31 10:40:40.316: D/TestServiceMain(24971): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:40:40.316: D/TestServiceMain(24971): runing runing
10-31 10:40:41.321: D/TestServiceMain(24971): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:40:41.321: D/TestServiceMain(24971): runing runing
10-31 10:40:42.321: D/TestServiceMain(24971): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:40:42.321: D/TestServiceMain(24971): runing runing
10-31 10:40:42.611: D/TestServiceMain(24971): MainActivity onDestroy()
10-31 10:40:42.626: D/TestServiceMain(24971): MainActivity unbindService()
10-31 10:40:42.641: I/TestService(24971): onUnbind~~~~~~~~~~~~~~~~
10-31 10:40:42.641: I/TestService(24971): onDestroy~~~~~~~~~~~
10-31 10:40:43.316: D/TestServiceMain(24971): runing runing
那麼再證實B選項第二種情況,但是如果沒有呼叫unbindService()方法的情況下,服務會終止嗎?(把 unbindService(conn); 註釋掉)日誌如下:
10-31 10:44:55.551: D/TestServiceMain(26043): runing runing
10-31 10:44:56.551: D/TestServiceMain(26043): runing runing
10-31 10:44:57.386: D/TestServiceMain(26043): StartService -- onclick
10-31 10:44:57.386: I/TestService(26043): onCreate~~~~~~~~~~
10-31 10:44:57.386: I/TestService(26043): onBind~~~~~~~~~~~~
10-31 10:44:57.561: D/TestServiceMain(26043): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:44:57.561: D/TestServiceMain(26043): runing runing
10-31 10:44:58.566: D/TestServiceMain(26043): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:44:58.566: D/TestServiceMain(26043): runing runing
10-31 10:44:59.561: D/TestServiceMain(26043): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:44:59.561: D/TestServiceMain(26043): runing runing
10-31 10:45:00.556: D/TestServiceMain(26043): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:45:00.556: D/TestServiceMain(26043): runing runing
10-31 10:45:01.571: D/TestServiceMain(26043): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:45:01.571: D/TestServiceMain(26043): runing runing
10-31 10:45:02.326: D/TestServiceMain(26043): MainActivity onDestroy()
10-31 10:45:02.341: E/ActivityThread(26043): Activity com.example.servicestest.MainActivity has leaked ServiceConnection [email protected] that was originally bound here
10-31 10:45:02.341: E/ActivityThread(26043): android.app.ServiceConnectionLeaked: Activity com.example.servicestest.MainActivity has leaked ServiceConnection [email protected] that was originally bound here
10-31 10:45:02.341: E/ActivityThread(26043): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:983)
10-31 10:45:02.341: E/ActivityThread(26043): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:877)
10-31 10:45:02.341: E/ActivityThread(26043): at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1959)
10-31 10:45:02.341: E/ActivityThread(26043): at android.app.ContextImpl.bindService(ContextImpl.java:1942)
10-31 10:45:02.341: E/ActivityThread(26043): at android.content.ContextWrapper.bindService(ContextWrapper.java:529)
10-31 10:45:02.341: E/ActivityThread(26043): at com.example.servicestest.MainActivity$2.onClick(MainActivity.java:40)
10-31 10:45:02.341: E/ActivityThread(26043): at android.view.View.performClick(View.java:4654)
10-31 10:45:02.341: E/ActivityThread(26043): at android.view.View$PerformClick.run(View.java:19438)
10-31 10:45:02.341: E/ActivityThread(26043): at android.os.Handler.handleCallback(Handler.java:733)
10-31 10:45:02.341: E/ActivityThread(26043): at android.os.Handler.dispatchMessage(Handler.java:95)
10-31 10:45:02.341: E/ActivityThread(26043): at android.os.Looper.loop(Looper.java:146)
10-31 10:45:02.341: E/ActivityThread(26043): at android.app.ActivityThread.main(ActivityThread.java:5602)
10-31 10:45:02.341: E/ActivityThread(26043): at java.lang.reflect.Method.invokeNative(Native Method)
10-31 10:45:02.341: E/ActivityThread(26043): at java.lang.reflect.Method.invoke(Method.java:515)
10-31 10:45:02.341: E/ActivityThread(26043): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
10-31 10:45:02.341: E/ActivityThread(26043): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
10-31 10:45:02.341: E/ActivityThread(26043): at dalvik.system.NativeStart.main(Native Method)
10-31 10:45:02.346: I/TestService(26043): onUnbind~~~~~~~~~~~~~~~~
10-31 10:45:02.346: I/TestService(26043): onDestroy~~~~~~~~~~~
10-31 10:45:02.556: D/TestServiceMain(26043): runing runing
10-31 10:45:03.556: D/TestServiceMain(26043): runing runing
10-31 10:45:04.561: D/TestServiceMain(26043): runing runing
此種情況會給出一個異常,就是因為沒有呼叫unbindService()造成的,但是服務確實結束了。so~ 選項B證實是正確的。
那麼順道證實下選項D。
10-31 10:48:46.376: D/TestServiceMain(26752): runing runing
10-31 10:48:47.366: D/TestServiceMain(26752): runing runing
10-31 10:48:48.381: D/TestServiceMain(26752): runing runing
10-31 10:48:49.361: D/TestServiceMain(26752): runing runing
10-31 10:48:49.841: D/TestServiceMain(26752): StartService -- onclick
10-31 10:48:49.846: I/TestService(26752): onCreate~~~~~~~~~~
10-31 10:48:49.846: I/TestService(26752): onBind~~~~~~~~~~~~
10-31 10:48:50.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:50.366: D/TestServiceMain(26752): runing runing
10-31 10:48:51.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:51.361: D/TestServiceMain(26752): runing runing
10-31 10:48:52.376: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:52.376: D/TestServiceMain(26752): runing runing
10-31 10:48:53.376: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:53.376: D/TestServiceMain(26752): runing runing
10-31 10:48:54.381: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:54.381: D/TestServiceMain(26752): runing runing
10-31 10:48:54.696: D/TestServiceMain(26752): StopService -- onclick
10-31 10:48:55.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:55.361: D/TestServiceMain(26752): runing runing
10-31 10:48:56.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:56.361: D/TestServiceMain(26752): runing runing
10-31 10:48:57.091: D/TestServiceMain(26752): StopService -- onclick
10-31 10:48:57.316: D/TestServiceMain(26752): StopService -- onclick
10-31 10:48:57.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:57.366: D/TestServiceMain(26752): runing runing
10-31 10:48:57.531: D/TestServiceMain(26752): StopService -- onclick
10-31 10:48:57.701: D/TestServiceMain(26752): StopService -- onclick
10-31 10:48:58.376: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:58.376: D/TestServiceMain(26752): runing runing
10-31 10:48:59.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:48:59.361: D/TestServiceMain(26752): runing runing
10-31 10:49:00.376: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:49:00.376: D/TestServiceMain(26752): runing runing
10-31 10:49:01.366: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:49:01.366: D/TestServiceMain(26752): runing runing
10-31 10:49:02.361: D/TestServiceMain(26752): runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
10-31 10:49:02.361: D/TestServiceMain(26752): runing runing
如日誌:先呼叫了onCreate()——————》 onBind() 但是呼叫stopService()方法並不能終止服務。
所以這道題的答案是D。
重點備註:1、基於本例,判斷服務在不在執行是根據日誌:
runing !!!!!!!!!!!!!!!! com.example.servicestest.TestService
來判斷的。
2、Timer 脫離主執行緒(就是說應用退出後),也會繼續執行的。 所以避免錯誤的實驗,比如:把 Timer 放到service 中,讓他重複列印一條語句,那麼就算service 退出了,依然會有日誌輸出。
相關推薦
Android中,關於service的啟動兩種方式描述不正確的是
碰到群友問的一個問題,說:關於service的啟動兩種方式描述不正確的是(如圖)? 當時看到這個問題有點糾結,糾結內容如下: A 選項沒有疑問,官網就是這麼說的 B選項就是我所糾結的地方,這個呼叫者如果退出了,那麼如果在onDestroy()中呼叫了unbin
Android開發中的Service的兩種啟動方式的坑
和大家熟悉的Activity元件一樣,service也是Android應用開程式發中常用的元件,它和acitivy一樣也有自己的生命週期,不同的是service是執行在後臺的,沒有同用戶直接互動的介面。 service的是有兩種啟動方式: 第一種是通過startserv
Android小知識-剖析Retrofit中網路請求的兩種方式
本平臺的文章更新會有延遲,大家可以關注微信公眾號-顧林海,包括年底前會更新kotlin由淺入深系列教程,目前計劃在微信公眾號進行首發,如果大家想獲取最新教程,請關注微信公眾號,謝謝! 在上一節《Android小知識-剖析Retrofit中ServiceMethod相關引數以及建立過程》介紹了動態代
android開啟另外的app兩種方式,內建到自己本身的app,重新開啟app,
android開啟另外的app兩種方式,內建到自己本身的app空間,重新開啟app空間, 目錄 1、內建到自己本身的app空間, 被開啟的app的activity的主配置檔案的程式碼編寫、 <activity android:n
Android開發中單元測試的兩種方式
Android開發中單元測試的兩種方式 一位優秀的程式設計師也同樣不能保證自己的程式沒有bug,因此編寫合適的測試程式是完全有必要的,這樣也會降低程式在後期出現各種奇奇怪怪bug的可能,降低維護成本,未雨綢繆將bug扼殺在搖籃之中。 看到網上有很多依舊用寫java單元測試的
Android: Android Studio簽名打包的兩種方式(zz)
信息 rda pan 相同 prop .cn 一個 一次 ack 註:給我們自己開發的app簽名,就代表著我自己的版權,以後要進行升級,也必須要使用相同的簽名才行。簽名就代表著自己的身份(即keystore),多個app可以使用同一個簽名。如果不知道簽名是啥意思,請自行百度
javascript教程系列40:DOM中操作樣式的兩種方式
AS color 單位 css 註意 pan col ntb javascrip 1 DOM中操作樣式的兩種方式 1 通過元素的style屬性 註意: 通過style屬性設置樣式時,css中要寫單位的屬性,在js代碼中也要加單位 //html <div id="bo
Android以JSONOject和GSON兩種方式解析json
length pre ray oid 字符 CA clas img name json文件如下: 將獲取到的json數據轉化為String形式 OkHttpClient client = new OkHttpClient(); R
操作系統,編程語言分類,執行python兩種方式,變量,內存管理,定義變量的三個特征
什麽 height 取代 沒有 一個 Coding 開發 軟件 簡單 操作系統 1、什麽是操作系統 操作系統位於計算機硬件與應用軟件之間 是一個協調、管理、控制計算機硬件資源與軟件資源的控制程序2、為何要有操作系統? 1、控制硬件 2、把對硬件的復雜
C#中Post請求的兩種方式發送參數鏈和Body的
連接 png ets return div 參數 try 發現 create POST請求 有兩種方式 一種是組裝key=value這種參數對的方式 一種是直接把一個字符串發送過去 作為body的方式 我們在postman中可以看到 sfdsafd sdfsdfds
關於H5頁面中生成圖片的兩種方式!
ima 前端 不能 圖片 項目 自定義 dom對象 技術分享 ron 前言: 我們在做項目過程中,經常會遇到自定義生成一張圖片並可以長按保存。長按保存圖片在微信等瀏覽器中默認就有,那麽對於生成圖片的有哪些方式呢? 方法一: 利用canvas繪制圖形,然後生成圖片 代碼如下:
testNG中dataprovider使用的兩種方式
pro ret urn expect highlight 參數化 sdn esp tin testNG的參數化測試有兩種方式:xml和dataprovider.個人更喜歡dataprovider,因為我喜歡把測試數據放在數據庫裏。 一.返回類型是Iterator<Ob
將Android專案開源到JCenter兩種方式
前言 開發中,或多或少都會用到無私的程式猿分享的開源專案,Androidstudio中使用開源也很方便 例如家喻戶曉的Rxjava,只需要一句話 compile 'io.reactivex:rxjava:1.1.6',就可以新增到專案中,時間久了,是不是自己也想試試開源一下自己的成果
mybatis中批量插入的兩種方式(高效插入)
一、mybiats foreach標籤 <insert id="insertBatch" parameterType="List"> INSERT INTO TStudent(name,age) <foreach collection="list" item="item" in
OL4中新增圖示的兩種方式的比較
前言:在ol中我們也可以新增一些圖示在地圖上,用於展示效果,較早期的版本OL提供一個overlay覆蓋物的方式,在OL3和OL4中這種用法不太多了,一個主要的原因它是通過HTML的方式的新增到地圖上,這種方式有一個很大的問題就是偏移,隨著你放大或者縮小可以看到圖示的位置明顯偏
Android中onTouch與onClick兩種監聽的完全解析
之前專案中做一個豎直方向的ViewPager效果(詳見我的另一篇博文),這幾天做了幾個改動,突然發現我設定的OnTouchListener對觸控事件的監聽突然不起作用了,琢磨了半天覺得問題就出在onTouch的返回值true還是false上,後來自己測試的時候發現不光與這個有關,與OnClickLi
SpringBoot中使用AMQ的兩種方式二(Java配置、註解方式)
使用@JmsListener註解方式 1. 工程目錄
iText G (Android)PDF文字定位書寫兩種方式介紹
閒言少敘,直接進入話題(相關基礎知識不瞭解,請使用百度之類惡補),有不當之處,請高人批准指正。。 方法一(絕對定位),參考形如: PdfContentByte pdfContentByte = pdfWriter.getDirectContent(); Base
vue中引入echarts的兩種方式
全域性引入 1. main.js中配置 import echarts from 'echarts' //引入echarts Vue.prototype.$echarts = echarts //引入元件 2. echarts在vue中的引用 <div id="
獲取IOC容器中的bean的兩種方式(id和class)的區別
// ClassPathXmlApplicationContext: 是 ApplicationContext的實現類,從類路徑下來載入配置檔案 ApplicationContext ctx=new ClassPathXmlApplicationContext("a