zoukankan      html  css  js  c++  java
  • Android开发之Service

    什么是Service?

    Android中的服务与Activity不同,他是不能与用户进行交互,自己也不能启动在后台运行的程序,当我们退出应用时,Service应用并没有结束,它仍然在后台运行。

    例子:

    我们播放音乐,此时又要去干别的事的时候。如果没有Services退出播放音乐的应用我们就听不到歌。

    如何获取启动Service实例?

    可以使用bindService()实现。

    初步了解Services的用法:

    代码:

     1 package com.example.hxdn.servicetest;
     2 
     3 import android.content.Intent;
     4 import android.support.v7.app.AppCompatActivity;
     5 import android.os.Bundle;
     6 import android.util.Log;
     7 import android.view.Menu;
     8 import android.view.MenuItem;
     9 import android.view.View;
    10 import android.widget.Button;
    11 
    12 public class MainActivity extends AppCompatActivity {
    13 
    14     private  static final String BiaoQian="MainActivity";
    15     private Button btn1=null;
    16     private Button btn2=null;
    17     @Override
    18     protected void onCreate(Bundle savedInstanceState) {
    19         super.onCreate(savedInstanceState);
    20         setContentView(R.layout.activity_main);
    21         Log.i(BiaoQian,"onCreate() executed");
    22         btn1=(Button)findViewById(R.id.btn1);
    23         btn2=(Button)findViewById(R.id.btn2);
    24         btn1.setOnClickListener(new View.OnClickListener() {
    25             @Override
    26             public void onClick(View v) {
    27                 Intent startIntent=new Intent(MainActivity.this,MyService.class);
    28                 startService(startIntent);
    29             }
    30         });
    31         btn2.setOnClickListener(new View.OnClickListener() {
    32             @Override
    33             public void onClick(View v) {
    34                 Intent stopIntent=new Intent(MainActivity.this,MyService.class);
    35                 stopService(stopIntent);
    36             }
    37         });
    38 
    39     }
    40 
    41     @Override
    42     public boolean onCreateOptionsMenu(Menu menu) {
    43         // Inflate the menu; this adds items to the action bar if it is present.
    44         getMenuInflater().inflate(R.menu.menu_main, menu);
    45         return true;
    46     }
    47 
    48     @Override
    49     public boolean onOptionsItemSelected(MenuItem item) {
    50         // Handle action bar item clicks here. The action bar will
    51         // automatically handle clicks on the Home/Up button, so long
    52         // as you specify a parent activity in AndroidManifest.xml.
    53         int id = item.getItemId();
    54 
    55         //noinspection SimplifiableIfStatement
    56         if (id == R.id.action_settings) {
    57             return true;
    58         }
    59 
    60         return super.onOptionsItemSelected(item);
    61     }
    62 }
    package com.example.hxdn.servicetest;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.util.Log;
    
    /**
     * Created by hxdn on 2015/9/16.
     */
    public class MyService extends Service {
        public final static  String TAG="MyService";
        @Override
        public void  onCreate()
        {
            super.onCreate();
            Log.i(TAG,"onCreate() executed");
        }
        @Override
        public  int onStartCommand(Intent intent,int flags,int startId)
        {
            Log.i(TAG, "onCommand() executed");
            return super.onStartCommand(intent, flags, startId);
    
        }
        @Override
        public  void  onDestroy()
        {
            super.onDestroy();
            Log.i(TAG, "onDestroy() executed");
        }
        @Override
       public IBinder onBind(Intent intent)
        {
            return null;
        }
    }
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.hxdn.servicetest">
     4 
     5     <application
     6         android:allowBackup="true"
     7         android:icon="@mipmap/ic_launcher"
     8         android:label="@string/app_name"
     9         android:theme="@style/AppTheme">
    10         <activity
    11             android:name=".MainActivity"
    12             android:label="@string/app_name">
    13             <intent-filter>
    14                 <action android:name="android.intent.action.MAIN" />
    15 
    16                 <category android:name="android.intent.category.LAUNCHER" />
    17             </intent-filter>
    18         </activity>
    19         <service android:name="com.example.hxdn.servicetest.MyService"></service>
    20     </application>
    21 
    22 </manifest>

    布局代码只是写两个按钮启动和关闭Setvice。

    注意点:

    1、Services与Activity同为四大组件都需要注册!

    2、如果Services已经创建过(onCreate()),且没有被销毁,接下来再启动Services(startService())只会执行(onStartCommand())。

    Service和Activity通信

    先贴上代码:

    MainActivity:

     1 package com.example.hxdn.servicetest;
     2 
     3 import android.content.ComponentName;
     4 import android.content.Intent;
     5 import android.content.ServiceConnection;
     6 import android.os.IBinder;
     7 import android.support.v7.app.AppCompatActivity;
     8 import android.os.Bundle;
     9 import android.util.Log;
    10 import android.view.Menu;
    11 import android.view.MenuItem;
    12 import android.view.View;
    13 import android.widget.Button;
    14 
    15 public class MainActivity extends AppCompatActivity {
    16 
    17     private  static final String BiaoQian="MyService";
    18     private Button btn1=null;
    19     private Button btn2=null;
    20     private Button btn3=null;
    21     private Button btn4=null;
    22     private MyService.MyBinder mybinder=null;
    23     private ServiceConnection serviceConnection=new ServiceConnection() {
    24         @Override
    25         public void onServiceConnected(ComponentName name, IBinder service) {
    26             Log.i(BiaoQian,"onServiceConnected() executed");
    27             mybinder=(MyService.MyBinder)service;
    28             mybinder.startDownLoad();
    29         }
    30 
    31         @Override
    32         public void onServiceDisconnected(ComponentName name) {
    33             Log.i(BiaoQian,"onServiceDisconnected() executed");
    34         }
    35     };
    36     @Override
    37     protected void onCreate(Bundle savedInstanceState) {
    38         super.onCreate(savedInstanceState);
    39         setContentView(R.layout.activity_main);
    40         Log.i(BiaoQian, "onCreate() executed");
    41         btn1=(Button)findViewById(R.id.btn1);
    42         btn2=(Button)findViewById(R.id.btn2);
    43         btn3=(Button)findViewById(R.id.btn3);
    44         btn4=(Button)findViewById(R.id.btn4);
    45         btn1.setOnClickListener(new View.OnClickListener() {
    46             @Override
    47             public void onClick(View v) {
    48                 Intent startIntent=new Intent(MainActivity.this,MyService.class);
    49                 startService(startIntent);
    50             }
    51         });
    52         btn2.setOnClickListener(new View.OnClickListener() {
    53             @Override
    54             public void onClick(View v) {
    55                 Log.i(BiaoQian, "click Stop Service button");
    56                 Intent stopIntent=new Intent(MainActivity.this,MyService.class);
    57                 stopService(stopIntent);
    58             }
    59         });
    60         btn3.setOnClickListener(new View.OnClickListener() {
    61             @Override
    62             public void onClick(View v) {
    63                 Intent bindIntent=new Intent(MainActivity.this,MyService.class);
    64                 bindService(bindIntent,serviceConnection,BIND_AUTO_CREATE);
    65             }
    66         });
    67         btn4.setOnClickListener(new View.OnClickListener() {
    68             @Override
    69             public void onClick(View v) {
    70                 Log.i(BiaoQian, "click Unbind Service button");
    71                unbindService(serviceConnection);
    72             }
    73         });
    74 
    75     }
    76 
    77     @Override
    78     public boolean onCreateOptionsMenu(Menu menu) {
    79         // Inflate the menu; this adds items to the action bar if it is present.
    80         getMenuInflater().inflate(R.menu.menu_main, menu);
    81         return true;
    82     }
    83 
    84     @Override
    85     public boolean onOptionsItemSelected(MenuItem item) {
    86         // Handle action bar item clicks here. The action bar will
    87         // automatically handle clicks on the Home/Up button, so long
    88         // as you specify a parent activity in AndroidManifest.xml.
    89         int id = item.getItemId();
    90 
    91         //noinspection SimplifiableIfStatement
    92         if (id == R.id.action_settings) {
    93             return true;
    94         }
    95 
    96         return super.onOptionsItemSelected(item);
    97     }
    98 }

    MyService:

     1 package com.example.hxdn.servicetest;
     2 
     3 import android.app.Service;
     4 import android.content.Intent;
     5 import android.os.Binder;
     6 import android.os.IBinder;
     7 import android.util.Log;
     8 
     9 /**
    10  * Created by hxdn on 2015/9/16.
    11  */
    12 public class MyService extends Service {
    13     public final static  String TAG="MyService";
    14     private MyBinder myBinder=new MyBinder();
    15     @Override
    16     public void  onCreate()
    17     {
    18         super.onCreate();
    19         Log.i(TAG,"onCreate() executed");
    20     }
    21     @Override
    22     public  int onStartCommand(Intent intent,int flags,int startId)
    23     {
    24         Log.i(TAG, "onCommand() executed");
    25         return super.onStartCommand(intent, flags, startId);
    26 
    27     }
    28     @Override
    29     public  void  onDestroy()
    30     {
    31         super.onDestroy();
    32         Log.i(TAG, "onDestroy() executed");
    33     }
    34     @Override
    35     public void  onRebind(Intent intent)
    36     {
    37         super.onRebind(intent);
    38         Log.i(TAG,"onRebind() executed");
    39     }
    40     @Override
    41     public  boolean  onUnbind(Intent intent)
    42     {
    43         Log.i(TAG,"onUnbind()");
    44         return super.onUnbind(intent);
    45 
    46     }
    47     @Override
    48    public IBinder onBind(Intent intent)//返回类型为IBinder,其主要作用是Service与外界交互的一种手段,
    49                                         // 而IBinder对象数据类型是接口。
    50     {
    51         return myBinder;
    52     }
    53     class MyBinder extends Binder
    54     {
    55         public void startDownLoad()
    56         {
    57             Log.i(TAG,"startDownLoad() executed");
    58         }
    59     }
    60 }

    这里我们新增了一个MyBinder类继承自Binder类,然后在MyBinder中添加了一个startDownload()方法用于在后台执行下载任务,当然这里并不是真正地去下载某个东西,只是做个测试,所以startDownload()方法只是打印了一行日志。

    我所理解的Activity与Services通信的机制是:

    1、首先Service里需要有一个Binder的类,类似构建起临时的契约。而且需要复写onBind(Intent intent),并返回一个Binder对象。

    2、在Activity里需要获得连接,所学需要ServiceConnection的匿名类,在里面重写了onServiceConnected(ComponentName name, IBinder service)

    方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。参数service便是MyService里的onBinder()方法返回的。

    便可通过这个这个实例调用Binder类里的方法,我们便可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。

    3、Activity与Service需要进行绑定

    Intent bindIntent=new Intent(MainActivity.this,MyService.class);
    bindService(bindIntent,serviceConnection,BIND_AUTO_CREATE);
    BIND_AUTO_CREATE:表示绑定后自动创建Service实例。

    解绑:
    unbindService(serviceConnection);

    注意点:
    如果我们既点击了Start Service按钮,又点击了Bind Service按钮会怎么样呢?这个时候你会发现,不管你是单独点击Stop Service按钮还是Unbind Service按钮,Service都不会被销毁,必要将两个按钮都点击一下,Service才会被销毁。也就是说,点击Stop Service按钮只会让Service停止,点击Unbind Service按钮只会让Service和Activity解除关联,一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。

    Service和Thread的关系

    service是后台进程并且运行在主线程,Thread是子线程。

    两者没有任何关系。

    Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。

    面对后台的耗时操作,我们可以在Service写一个子线程。

    那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

    一个较为标准的Service:

     1 @Override
     2 public int onStartCommand(Intent intent, int flags, int startId) {
     3     new Thread(new Runnable() {
     4         @Override
     5         public void run() {
     6             // 开始执行后台任务
     7         }
     8     }).start();
     9     return super.onStartCommand(intent, flags, startId);
    10 }
    11 
    12 class MyBinder extends Binder {
    13 
    14     public void startDownload() {
    15         new Thread(new Runnable() {
    16             @Override
    17             public void run() {
    18                 // 执行具体的下载任务
    19             }
    20         }).start();
    21     }
    22 
    23 }

    修改by:http://blog.csdn.net/guolin_blog/article/details/11952435

  • 相关阅读:
    leetcode 78. 子集 JAVA
    leetcode 91. 解码方法 JAVA
    leetcode 75. 颜色分类 JAVA
    leetcode 74 搜索二维矩阵 java
    leetcode 84. 柱状图中最大的矩形 JAVA
    last occurance
    first occurance
    classical binary search
    LC.234.Palindrome Linked List
    LC.142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/hsshy/p/4815060.html
Copyright © 2011-2022 走看看