• 安卓之service简单介绍


    一 什么是Service
    二 如何使用Service
    Service的生命周期


     

    一 什么是Service

    Service,看名字就知道跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,也需要在配置文件里注册,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用, Context.startService() 和 Context.bindService()。

    两种启动Service的方式有所不同。这里要说明一下的是如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好在 Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。

    什么时候需要Service呢?比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。

    二 如何使用Service

    那接下来用代码来说明一下怎么使用Service,这里我们要讲的是Local Service也就是你自己的一个Service, 你也可以操作别的应用程序的service如果它允许你那么去做的话,这就设计到一个比较麻烦的东西interprocess communication (IPC),在不同的进程中通信的机制,这个我自己也还没有用过,等用了以后再跟大伙说说,通常情况下Local的就够用啦。

    跟Activity一样首先你要写一个类继承自android.app.Service,在这里我叫他TestService
    代码如下:

    package jason.tutorial;
    
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    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 static final String TAG = "TestService";
    private NotificationManager nm;
    
    @Override
    public IBinder onBind(Intent i) {
    Log.e(TAG, "============> TestService.onBind");
    return null;
    }
    
    public class LocalBinder extends Binder {
    TestService getService() {
    return TestService.this;
    }
    }
    
    @Override
    public boolean onUnbind(Intent i) {
    Log.e(TAG, "============> TestService.onUnbind");
    return false;
    }
    
    @Override
    public void onRebind(Intent i) {
    Log.e(TAG, "============> TestService.onRebind");
    }
    
    @Override
    public void onCreate() {
    Log.e(TAG, "============> TestService.onCreate");
    nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    showNotification();
    }
    
    @Override
    public void onStart(Intent intent, int startId) {
    Log.e(TAG, "============> TestService.onStart");
    }
    
    @Override
    public void onDestroy() {
    nm.cancel(R.string.service_started);
    Log.e(TAG, "============> TestService.onDestroy");
    }
    
    private void showNotification() {
    Notification notification = new Notification(R.drawable.face_1,
    "Service started", System.currentTimeMillis());
    
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
    new Intent(this, TestServiceHolder.class), 0);
    
    // must set this for content view, or will throw a exception
    notification.setLatestEventInfo(this, "Test Service",
    "Service started", contentIntent);
    
    nm.notify(R.string.service_started, notification);
    }
    }
    

    其中用到Notification是为了明显地表明Service存活的状态,这样看上去直观一点,更多关于Notification的内容请参考前面的文章.

    public class LocalBinder extends Binder {
    TestService getService() {
    return TestService.this;
    }
    }

    这个方法是为了让调用者得到这个Service并操作它。
    Service本身就这样简单了,你需要做什么就在onCreate和onStart里做好了,起个线程什么的。

    再看一下它的调用者,TestServiceHolder

    package jason.tutorial;
    
    import android.app.Activity;
    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.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class TestServiceHolder extends Activity {
    private boolean isBound;
    private TestService boundService;
    
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.test_service_holder);
    	setTitle("Service Test");
    
    	initButtons();
    }
    
    private ServiceConnection connection = new ServiceConnection() {
    	public void onServiceConnected(ComponentName className, IBinder service) {
    		boundService = ((TestService.LocalBinder)service).getService();
    
    		Toast.makeText(TestServiceHolder.this, "Service connected",
    		Toast.LENGTH_SHORT).show();
    	}
    
    	public void onServiceDisconnected(ComponentName className) {
    		// unexpectedly disconnected,we should never see this happen.
    		boundService = null;
    		Toast.makeText(TestServiceHolder.this, "Service disconnected",
    		Toast.LENGTH_SHORT).show();
    	}
    };
    
    private void initButtons() {
    	Button buttonStart = (Button) findViewById(R.id.start_service);
    	buttonStart.setOnClickListener(new OnClickListener() {
    		public void onClick(View arg0) {
    		startService();
    	}
    	});
    
    	Button buttonStop = (Button) findViewById(R.id.stop_service);
    	buttonStop.setOnClickListener(new OnClickListener() {
    		public void onClick(View arg0) {
    		stopService();
    	}
    	});
    
    	Button buttonBind = (Button) findViewById(R.id.bind_service);
    	buttonBind.setOnClickListener(new OnClickListener() {
    		public void onClick(View arg0) {
    		bindService();
    	}
    	});
    
    	Button buttonUnbind = (Button) findViewById(R.id.unbind_service);
    	buttonUnbind.setOnClickListener(new OnClickListener() {
    		public void onClick(View arg0) {
    		unbindService();
    	}
    	});
    }
    
    private void startService() {
    	Intent i = new Intent(this, TestService.class);
    	this.startService(i);
    }
    
    private void stopService() {
    	Intent i = new Intent(this, TestService.class);
    	this.stopService(i);
    }
    
    private void bindService() {
    	Intent i = new Intent(this, TestService.class);
    	bindService(i, connection, Context.BIND_AUTO_CREATE);
    	isBound = true;
    }
    
    private void unbindService() {
    	if (isBound) {
    		unbindService(_connection);
    		isBound = false;
    	}
    }
    }
    

    这里可以看到两种启动方法,start和bind,当然都是通过intent调用的,在intent中指明要启动的 Service的名字,stop也一样

    private void startService() {
    	Intent i = new Intent(this, TestService.class);
    	this.startService(i);
    }
    
    private void stopService() {
    	Intent i = new Intent(this, TestService.class);
    	this.stopService(i);
    }
    
    

    对于bind的话,需要一个ServiceConnection对象

    private ServiceConnection connection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
    	boundService = ((TestService.LocalBinder)service).getService();
    
    	Toast.makeText(TestServiceHolder.this, "Service connected",
    	Toast.LENGTH_SHORT).show();
    }
    
    public void onServiceDisconnected(ComponentName className) {
    // unexpectedly disconnected,we should never see this happen.
    	boundService = null;
    	Toast.makeText(TestServiceHolder.this, "Service disconnected",
    	Toast.LENGTH_SHORT).show();
    }
    };


    用来把Activity和特定的Service连接在一起,共同存亡,具体的生命周期细节下一段来讲。

    三 Service的生命周期

    Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy
    我们有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。


    1 通过startService

       Service会经历 onCreate -> onStart,  stopService的时候直接onDestroy

       如果是调用者(TestServiceHolder)自己直接退出而没有调用stopService的话,Service会一直在后台运行。
       下次TestServiceHolder再起来可以stopService。

    2 通过bindService   

        Service只会运行onCreate, 然后会有onBind,这个时候 TestServiceHolder 和TestService绑定在一起

       TestServiceHolder 退出了,Srevice就会调用onUnbind->onDestroyed     ,所谓绑定在一起就共存亡了。

    那有同学问了,要是这几个方法交织在一起的话,会出现什么情况呢?
    一个原则是Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又 bindService,Service只被创建一次。如果先是bind了,那么start的时候就直接运行Service的onStart方法,如果先 是start,那么bind的时候就直接运行onBind方法。如果你先bind上了,就stop不掉了,对啊,就是stopService不好使了,只 能先UnbindService, 再StopService,所以是先start还是先bind行为是有区别的。

    大家有兴趣可以回去点点按钮看看log,多看几遍log就知道了。

  • 相关阅读:
    HTML5中drag和drop使用
    E
    D
    杜教BM(解决线性递推式的模板)
    Myeclipse下载安装破解详细版
    D
    IDEA-连接MySQL连不上
    E
    C
    D. Ball(树状数组三维排序,求是否存在三个值都比自己大的人)
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3243729.html
Copyright © 2020-2023  润新知