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 com.example.servicestest.MainActivity$1@42806830 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 com.example.servicestest.MainActivity$1@42806830 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 退出了,依然会有日志输出。






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值