关闭

3.service的使用流程

113人阅读 评论(0) 收藏 举报
分类:

1.继承Service

这里写图片描述

2.实现service的两种方式(startService,bindservice)
在通过bind方式启动service之后,再通过start方式启动之时,只会调用onStartCommand而不会onCreate
2.1 startService启动service
注:一旦通过startService,可在同一应用中再次执行startService操作,而在新的启动中,不在执行onCreate,而是执行startCommand和onstart,而且在一个应用中,多次startService,关闭它只需要一次。

service代码

public class MyService extends Service {

private static final String TAG = "MyService";

int i = 0;


@Override
public void onCreate() {
super.onCreate();
        Toast.makeText(this, "开启服务" + i ,2000).show();
        Log.d(TAG , "onCreate : " + i);
i++;
    }

@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
        Log.d(TAG , "onStart");
    }

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG , "onStartCommand");
        Toast.makeText(this, intent.getStringExtra("from"), 2000).show();
return super.onStartCommand(intent, flags, startId);
    }

@Override
public void onDestroy() {
        Log.d(TAG , "onDestroy");
        Toast.makeText(this, "关闭服务" ,2000).show();
super.onDestroy();
//        stopSelf();
}
}

通过startService方法调用

Intent intent = null;//new Intent();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
intent = new Intent(this, MyService.class);
intent.putExtra("from","mian1");

        findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
                startService(intent);
            }
        });

        findViewById(R.id.button4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
                stopService(intent);
            }
        });

        findViewById(R.id.button9).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//                stopService(intent);
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
            }
        });

    }

2.2 bindService启动(有点小麻烦)
可以通过代理机制在activity中调用service中的方法,奇怪的问题是:在unbind–》ondestroy之后,activity调用通过“吃饭”和“打小胖子”方法,toast依然可以show

1.service实现

package com.lunch.wushengqi.mymedio;

import android.app.Service;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MyService extends Service {

private static final String TAG = "MyService";

int i = 0;


@Override
public void onCreate() {
super.onCreate();
            Toast.makeText(this, "开启服务" + i ,2000).show();
            Log.d(TAG , "onCreate : " + i);
i++;
        }

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//        throw new UnsupportedOperationException("Not yet implemented");
Log.d(TAG , "onBind");
        //返回的binder对象在activity中被实现,binder中存放的是service的对象
return new MyBinder(this);
    }



@Override
public boolean onUnbind(Intent intent) {
        Log.d(TAG , "onUnbind");
return super.onUnbind(intent);
    }

@Override
public void onRebind(Intent intent) {
        Log.d(TAG , "onRebind");
super.onRebind(intent);
    }

@Override
public void onDestroy() {
        Log.d(TAG , "onDestroy");
        Toast.makeText(this, "关闭服务" ,2000).show();
super.onDestroy();
//        stopSelf();
}

public void eat(){
        toast("吃饭");
    }

public void da(){
        toast("打小胖子");
    }

public void toast(String text){
        Toast.makeText(this, text ,2000).show();
    }


}

2.binder的实现

package com.lunch.wushengqi.mymedio;

import android.os.Binder;

/**
 * Created by Administrator on 2016/5/28.
 */
public class MyBinder extends Binder {

private MyService myService;

public MyBinder(MyService myService){
this.myService = myService;
    }

public MyService getServices(){
return myService;
    }
}

3.Activity中实现binderservice

package com.lunch.wushengqi.mymedio;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class Main2Activity extends AppCompatActivity {

    Intent bindIntent = null;

private MyService myService = null;

    ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
            //通过IBinder代理,获取service服务中public IBinder onBind(Intent intent)方法返回的自定义binder对象,并向下转型获取其中的内容

myService = ((MyBinder)service).getServices();
        }

@Override
public void onServiceDisconnected(ComponentName name) {

        }
    };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        findViewById(R.id.button7).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//                startIntent = new Intent(Main2Activity.this, MyService.class);
bindIntent = new Intent(Main2Activity.this, MyService.class);

                bindService(bindIntent, connection, Context.BIND_AUTO_CREATE);
            }
        });
        findViewById(R.id.button8).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//                startIntent = new Intent(Main2Activity.this, MyService.class);
unbindService(connection);
            }

        });

        findViewById(R.id.eat).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myService.eat();
            }
        });

        findViewById(R.id.da).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myService.da();
            }
        });


    }
}

IntentService(按start顺序执行)(记得看源码)
启动方式和startService一样,但是执行顺序和start顺序保持一致。其特点在于,在service中默认开启有序的子线程(一个service一个子线程),执行顺序和start顺序一致,我们只需要在protected void onHandleIntent(Intent intent) 方法中实现我们要实现的逻辑即可。

这里写图片描述

三、 拓展知识(进程和生命周期):
Android操作系统尝试尽可能长时间保持应用的进程,但当可用内存很低时要移走一部分进程。哪些程序可以运行,哪些要被销毁?答案是:重要级别低的进程可能被淘汰。
按照重要性排列,一共可以分成5级:

1、前台运行进程:
用户此时需要处理和显示的进程。符合下列条件任何一个,这个进程就被认为是前台运行进程。
与用户正发生交互;
它控制一个与用户交互的必须的基本的服务;
一个正在调用生命周期回调方法的ervice(如onCreate()、onStar()、onDestroy());
一个正在运行onReceive()方法的广播接收对象。
销毁前台运行进程是系统万不得已的、最后的选择——当内存不够系统继续运行下去时,杀掉一些前台进程来保证能够响应用户的需求。
2、可用进程:
一个可用进程没有任何前台组件,但它仍然可以影响到用户的界面。下面情况发生时,可以称该进程为可用进程。
它是一个非前台的activity,但对用户仍然可用(onPause()方法已经被调用)。例如:前台的activity是一个允许上一个activity可见的对话框。也就是说当前activity中是一个对话框,对话框之外的地方能看到前一个activity的界面。

3、服务进程:
服务进程是一个通过调用startService()方法启动的服务,并且不属于前两种情况。尽管服务进程没有直接被用户看到,但他们确实是用户所关心的,比如后台播放音乐或网络下载数据,所以系统保证他们的运行。

4、后台进程:
一个后台进程就是非当前正在运行的activity(activity的onStop()方法已经被调用),他们不会对用户体验造成直接的影响,当没有足够内存来运行前台可见程序时,他们将会被终止。
通常,后台进程会有很多个在运行,LRU最近使用程序列表来保证经常运行的activity能最后一个被终止。

5、空线程:
一个空线程没有运行任何可用应用程序,保留他们的唯一原因是为了设立一个缓存机制,来加快组件启动的时间。系统经常杀死这些内存来平衡系统的整个系统的资源,进程缓存和基本核心缓存之间的资源。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3192次
    • 积分:146
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    最新评论