Android Service基本使用(包含IntentService)

Android Service基本使用

参考:(下面两个连接更详细)

https://blog.csdn.net/javazejian/article/details/52426425

https://blog.csdn.net/javazejian/article/details/52709857

一、什么是Service

Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行.

二、创建Service的两种方式

· 启动状态

  当应用组件(如 Activity)通过调用 startService() 启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响,除非手动调用才能停止服务, 已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。

被开启的service通过其他组件调用 startService()被创建。

  这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。

  当service被停止时,系统会销毁它。

 

· 绑定状态

  当应用组件通过调用 bindService() 绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。 仅当与另一个应用组件绑定时,绑定服务才会运行。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

被绑定的service是当其他组件(一个客户)调用bindService()来创建的。

  客户可以通过一个IBinder接口和service进行通信。

  客户可以通过 unbindService()方法来关闭这种连接。

  一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service。

 

三、生命周期

 

四、具体实现

1startService():

public class MyService extends Service {
    public MyService() {
    }

    /**
     * 绑定服务时才会调用,但必须要写
     */
    
@Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        
throw new
UnsupportedOperationException("Not yet implemented");
    }

    /**
     * *首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。
     * 如果服务已在运行,则不会调用此方法。该方法只被调用一次
     */
    
@Override
    public void onCreate() {
        System.out.println("onCreate invoke");
        super.onCreate();
    }

    /**
     * 每次通过startService()方法启动Service时都会被回调。
     */
    
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("onStartCommand invoke");
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 销毁回调
     */
    
@Override
    public void onDestroy() {
        System.out.println("onDestroy invoke");
        super.onDestroy();
    }
}

 

具体调用:

开启

intent.setClass(MainActivity.this,MyService.class);
startService(intent);

停止

intent.setClass(MainActivity.this,MyService.class);
stopService(intent);

 

 

(2)bindService():

 

public class MyBindService extends Service {

    private MyBinder myBinder = new MyBinder();
    private final static String TAG = "MyBindService";
    private int count;
    private boolean quit;
    private Thread thread;

    public MyBindService() {
    }


    /**
     * 创建Binder对象,返回给客户端即Activity使用,提供数据交换的接口
     */
    
public class MyBinder extends Binder{
        // 声明一个方法,getService。(提供给客户端调用)
        
MyBindService getService(){
            // 返回当前对象LocalService,这样我们就可在客户端端调用Service的公共方法了
            
return MyBindService.this;
        }
    }

    /**
     * 把Binder类返回给客户端
     */
    
@Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "Service is invoke Created");
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 每间隔一秒count加1 ,直到quit为true。
                
while (!quit) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        });
        thread.start();
    }
    /**
     * 公共方法
     *
@return
     
*/
    
public int getCount(){
        return count;
    }

    /**
     * 解除绑定时调用
     */
    
@Override
    public boolean onUnbind(Intent intent) {
        Log.i(TAG, "Service is invoke onUnbind");
        return super.onUnbind(intent);
    }

    /**
     * 销毁时调用
     */
    
@Override
    public void onDestroy() {
        Log.i(TAG, "Service is invoke Destroyed ");
        this.quit = true;
        super.onDestroy();
    }
}

 

 

具体调用:

 

ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        MyBindService.MyBinder binder = (MyBindService.MyBinder) iBinder;
        mService = binder.getService();
    }

    /**
     * Android 系统会在与服务的连接意外中断时(例如当服务崩溃或被终止时)调用该方法。注意:当客户端取消绑定时,系统“绝对不会”调用该方法。
     */
    
@Override
    public void onServiceDisconnected(ComponentName componentName) {
        if(mService != null){
            mService = null;
        }
    }
};

 

 

case R.id.btn_main_get_data:
                if (mService != null) {
                    // 通过绑定服务传递的Binder对象,获取Service暴露出来的数据

                    
Log.i(TAG, "从服务端获取数据:" + mService.getCount());
                } else {

                    Log.i(TAG, "还没绑定呢,先绑定,无法从服务端获取数据");
                }
                break;
            case R.id.btn_main_bind:
                Log.i(TAG, "绑定调用:bindService");
                intent.setClass(MainActivity.this,MyBindService.class);
                //调用绑定方法
                
bindService(intent, conn, Service.BIND_AUTO_CREATE);
                break;
            case R.id.btn_main_unBind:
                Log.i(TAG, "解除绑定调用:unbindService");
//              解除绑定
                
if(mService!=null) {
                    mService = null;
                    unbindService(conn);
                }
                break;

 

五、IntentService 的使用

 

它本质是一种特殊的Service,继承自Service并且本身就是一个抽象类

它可以用于在后台执行耗时的异步任务,当任务完成后会自动停止

它拥有较高的优先级,不易被系统杀死(继承自Service的缘故),因此比较适合执行一些高优先级的异步任务

它内部通过HandlerThread和Handler实现异步操作

创建IntentService时,只需实现onHandleIntent和构造方法,onHandleIntent为异步方法,可以执行耗时操作

最后任务都执行完成后,IntentService自动销毁

 

 

public class MyIntentService extends IntentService {

    private final static String TAG = MyIntentService.class.getSimpleName();
    public static final String DOWNLOAD_URL="download_url";
    public static final String INDEX_FLAG="index_flag";

    public  static UpdateUIListener mUpdateUIListener;

    public MyIntentService() {
        super("MyIntentService");
    }

    public interface UpdateUIListener{
        void updateUI(Message message);
    }

    public static void setUpdateUIListener(UpdateUIListener updateUIListener){
        mUpdateUIListener = updateUIListener;
    }



    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //在子线程中进行网络请求
        
Bitmap bitmap=downLoadBitmap(intent.getStringExtra(DOWNLOAD_URL));
        Message msg1 = new Message();
        msg1.what = intent.getIntExtra(INDEX_FLAG,0);
        msg1.obj =bitmap;
        //通知主线程去更新UI
        
if(mUpdateUIListener!=null){
            mUpdateUIListener.updateUI(msg1);
        }
        //mUIHandler.sendMessageDelayed(msg1,1000);

        
Log.e(TAG,"onHandleIntent");
    }

    //----------------------重写一下方法仅为测试------------------------------------------
    
@Override
    public void onCreate() {
        Log.e(TAG,"onCreate");
        super.onCreate();
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG,"onStartCommand");
        return super.onStartCommand(intent, flags, startId);

    }

    /**
     * 最后任务都执行完成后,IntentService自动销毁
     */
    
@Override
    public void onDestroy() {
        Log.e(TAG,"onDestroy");
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"onBind");
        return super.onBind(intent);
    }



    private Bitmap downLoadBitmap(String urlString){
        HttpURLConnection connection = null;
        BufferedInputStream in = null;
        Bitmap bitmap=null;
        try {
            final URL url = new URL(urlString);
            connection = (HttpURLConnection) url.openConnection();
            in = new BufferedInputStream(connection.getInputStream(), 8 * 1024);
            bitmap= BitmapFactory.decodeStream(in);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        return bitmap;

    }
}

 

 

调用:

public class IntentServiceActivity extends AppCompatActivity implements MyIntentService.UpdateUIListener{

    private static ImageView iv_intent_service_photo;
    /**
     * 图片地址集合
     */
    
private String url[] = {
            "https://img-blog.csdn.net/20160903083245762",
            "https://img-blog.csdn.net/20160903083252184",
            "https://img-blog.csdn.net/20160903083257871",
            "https://img-blog.csdn.net/20160903083257871",
            "https://img-blog.csdn.net/20160903083311972",
            "https://img-blog.csdn.net/20160903083319668",
            "https://img-blog.csdn.net/20160903083326871"
    
};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);
        initView();
        showPhoto();
    }

    private void showPhoto() {
        Intent intent = new Intent(this,MyIntentService.class);
        for (int i=0;i<7;i++) {//循环启动任务
            
intent.putExtra(MyIntentService.DOWNLOAD_URL,url[i]);
            intent.putExtra(MyIntentService.INDEX_FLAG,i);
            startService(intent);
        }
        MyIntentService.setUpdateUIListener(this);
    }

    private void initView() {
        iv_intent_service_photo = findViewById(R.id.iv_intent_service_photo);
    }

    private static final Handler mUIHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            iv_intent_service_photo.setImageBitmap((Bitmap) msg.obj);
        }
    };

    @Override
    public void updateUI(Message message) {
        mUIHandler.sendMessageDelayed(message,message.what * 1000);
    }
}

 

 源码地址:https://download.csdn.net/download/silence_sep/10435385

猜你喜欢

转载自blog.csdn.net/silence_sep/article/details/80434198