android四大组件service

1、Service与Activity

service与activity都是android的基本组件,并且都是Context的子类,可以把service当作是没有界面的activity。与activity一样,不能在主线程中作耗时操作。都必须在清单文件中配置。

2、Service两种启动服务的方式和不同。

对于为什么会有两咱启动方式,他们是合适不同的场景的。使用startService启动的服务,它不会随着启动它的组件生命周期结束而结束,只要不调用停止服务或者手机结束进程,服务将一直处于运行中。

而通过bindStart()启动的服务是与启动它的组件生命周期相关联。如果启动它的组件销毁了,那么通过启动它的服务也就销毁了。

1. StartService()的生命周期:
  1. onCreate()——如果服务已经创建,则不会再走onCreate()方法。

  2. onStartCommand—-每一次调用都会执行:

    当其它组件,比如一个activity,通过调用startService()请求started方式的服务时,系统将会调用本方法。 一旦本方法执行,服务就被启动,并在后台一直运行下去。 如果你的代码实现了本方法,你就有责任在完成工作后通过调用stopSelf()或stopService()终止服务。 (如果你只想提供bind方式,那就不需要实现本方法。)

  3. onStart()——每一次调用都会执行

  4. onDesotry()——如果不调用.stopService()或者调用Service.stopSelfResult(),service将一直处于开启的状态;

这类服务由其它组件调用startService()来创建。然后保持运行,且必须通过调用stopSelf()自行终止。其它组件也可通过调用stopService() 终止这类服务。服务终止后,系统会把它销毁。

2、 通过bindService()的方式启动启动服务

当其它组件需要通过bindService()绑定服务时(比如执行RPC),系统会调用本方法。 在本方法的实现代码中,你必须返回IBinder来提供一个接口,客户端用它来和服务进行通信。 你必须确保实现本方法,不过假如你不需要提供绑定,那就返回null即可。

  1. bindService()— 调用

  2. onCreate()—–首先会走onCreate()方法

  3. onBind()——-绑定服务

  4. Service running—–服务正在运行中

  5. onUnbind()——-解除绑定

  6. onDesotry()——销毁服务

服务由其它组件(客户端)调用bindService()来创建。然后客户端通过一个IBinder接口与服务进行通信。客户端可以通过调用unbindService()来关闭联接。多个客户端可以绑定到同一个服务上,当所有的客户端都解除绑定后,系统会销毁服务。(服务不需要自行终止。)

3、对于两种启动方式的混合启动。

通过startService()方式启动服务,服务就可以做到长驻内存中(不依赖于组件)。使用bindService()的方式启动服务,服务与绑定组件相依存,并且通过bind的方式可以与service进行很多的交互,在conn中可以获取服务中的信息:比如说连接的状态,如果有下载任务,还可以得到下载的进度,情况等。

但是有时候用过这两种服务的混合开启这种情况使用的也比较多,比如说音乐播放器必须运行在服务中,但又需要被前台activity调用这就要用混合服务的方式启动了。
先startService(),再bindService(),销毁时先unbindService(),再stopService()。

4 、IntentService

intentService可能使用的人比较少,甚至很多人都没听过。但intentService是非常好用和适用的。

利用继承Service写的服务通过startService()启动服务,这种服务一旦启动,就处于运行状态,如果想要在线程执行后停止服务,只能调用 stopSelf()的方法。
为了方便起见,也是减少一些可能发生的错误,比如说经常忘记开启,或者调用stopSelf()的方法。Android中提供了一个IntentService()类,这个类可以简单的创建一个异步的,会自动停止的服务。
IntentService的执行步骤:

  • 创建一个子线程,并且执行onStartCommand()中收到的intent。

  • 创建一个工作队列,每次向onHandleIntent()传入一个intent,

  • 处理完所有的请求后,自动调用stopSelf()停止服务。

    详见实例3

5、Service与Activity之间的通信和传递数据;

1、activity向service发送数据比较简单,与activity之间传递数据一样。

Intent intent =new Intent(this,MyService.class);

intent.putExtra(“name”,”yu”);

startService(intent);

String name=intent.getStringExtra(“name”);

Log.i(TAG,name);

2、service向activity传递数据或者更新UI

如果需要数据持久化:

1、在service得到网络数据保存到sp中数据,在activity中从sp中取出数据更新UI;

2、在service中得到网络数据保存到数据库中,在activity中查询数据库,并更新UI
如果不需要持久化:

3、能过BroadcastReceiver把service中的数据传递给activity,
4、如果服务通过bindService的方式启动,还可以通过onBind()方法来传递数据给activity


6、如何用Service开启一个长期运行,定时更新的任务。比如天气,或者新闻每隔三小时更新;

  1. 在activity中启动服务。
  2. 在服务中的onStartCommand中开启子线程,连网得到网络数据,并且调用AlermManager定时,用PendingIntent得到广播,并发送给广播。
  3. 在广播的onReceive()中再次启动服务,这样就形成了一个长期的在后台运行,并且定时刷新的服务。

    详细实例4


1、通过startService启动服务代码:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService(new Intent(MainActivity.this,MyStartService.class));

    }
}

在MyStartService()中的代码:

public class MyStartService extends Service {
    private static final String TAG="MyStartService";
    //如果服务已经开启了,调用将不会再走onCreate()的方法
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG,"service onCreate()");
    }
    //每一次调用都是执行onStartCommand代码,在这段代码中主要做onStart()方法前的一些工作
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG,"service onStartCommend()");
        return super.onStartCommand(intent, flags, startId);
    }
    //onStart方法是在onStartCommand执行后走的方法。
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.i(TAG, "service onStart()");
    }
   //销毁服务;
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "service onDestory()");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

运行结果:第一次走了onCreate()的方法,再次则没有走onCreate()

这里写图片描述

2、通过bindService()启动服务代码

public class MyBindService extends Service {
    private static final String TAG = "MyBindService";

    //创建服务;
    @Override
    public void onCreate() {
        Log.i(TAG, "service onCreate()");
        super.onCreate();
    }

    //绑定服务,在绑定的服务中返回一个Bind对象;
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "service onBind()");
        return mBinder;
    }
    //销毁服务
    @Override
    public void onDestroy() {
        Log.i(TAG, "service onDestory()");
        super.onDestroy();
    }

    private MyBinder mBinder = new MyBinder();

    //创建MyBinder,继承Binder,调用bind启动服务时,把MyBindService返回
    public class MyBinder extends Binder {
        public MyBindService getService() {
            return MyBindService.this;
        }
    }
}

在Activity中调用:注意!通过绑定的服务会随着组件的结束而结束,在onDestory()中调用解除绑定代码

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //通过startService()的方式启动服务;
        //   startService(new Intent(MainActivity.this,MyStartService.class));

        //通过bindService()的方式启动服务;
        Intent intent = new Intent(MainActivity.this, MyBindService.class);
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {


        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

    };

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();

    }
}

效果图:当Activity执行了onDestory()时,服务也就销毁了
这里写图片描述


3、 intentService实例:

public class HelloIntentService extends IntentService {

  /** 
   * 构造方法是必需的,必须用工作线程名称作为参数
   * 调用父类的[http://developer.android.com/reference/android/app/IntentService.html#IntentService(java.lang.String) IntentService(String)]构造方法。
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }

  /**
   * IntentService从缺省的工作线程中调用本方法,并用启动服务的intent作为参数。 
   * 本方法返回后,IntentService将适时终止这个服务。
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // 通常我们会在这里执行一些工作,比如下载文件。
      // 作为例子,我们只是睡5秒钟。
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}

继承IntentService后,增加了一个构造方法和一个onHandleIntent()方法的实现。

还可以加上其他方法,比如onCreate()、onStartCommand()、onDestroy(), 请确保调用一下父类的实现代码,以便IntentService能正确处理工作线程的生命周期。


实例4、在后台定时数据更新为例,比如说每隔三小时天气更新。
在activity中代码:

/**
 * 如何做一个定时的,在后台运行的长期任务,比如天气,或者新闻每小时更新?
 *
 * 在activity中启动了service,然后在service中每隔10秒中启动广播,这样onReceive()方法得到执行,
 在广播中再次开启service,这样就形成一个永久的循环,一个长期的在后台运行的任务也就启动起来。
 */
public class MainActivity extends Activity  {
   private TextView tv_time;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_time= (TextView) findViewById(R.id.tv_time);
        Intent intent=new Intent(this,AutoService.class);
        startService(intent);
    }

}

在AutoService中代码:

public class AutoService extends Service {
    private static final String TAG="AutoService";
    private String str_time="";
    //不需要绑定
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    //onStartCommand在onStart()方法前运行;
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       new Thread(new Runnable() {
           @Override
           public void run() {
               //开启子线程,在这里做耗时操作;比如说获取天气信息;

               Log.i(TAG, getTime());

           }
       }).start();
        AlarmManager manager= (AlarmManager) getSystemService(ALARM_SERVICE);
        int time=10*1000;
        long triggerAtTIME= SystemClock.elapsedRealtime()+time;
        Intent i=new Intent(this,AutoBroadcastReceiver.class);
        PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
        manager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTIME, pi);
        return super.onStartCommand(intent, flags, startId);
    }

    public String getTime(){
        SimpleDateFormat sdf =new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss ");
        Date date=new Date(System.currentTimeMillis());
        String str=sdf.format(date);
        return str;
    }
}

在AutoBroadcastReceiver中代码:

public class AutoBroadcastReceiver extends BroadcastReceiver {
    public static final String TAG="AutoBroadcaseReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context, AutoService.class);
        context.startService(i);
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值