• 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

  • 相关阅读:
    用.NET Compact Framework创建图像按钮
    .netCF中后台多线程与UI界面交互的冻结问题
    参考网站
    PPC全屏(C#)(转)
    推荐一个.net cf的开源网站
    在Windows Mobile中应用智能设备框架(Smart Device Framework)
    使用飞信框架(Remotesoft DOTNET Linker)使.net程序脱离.net框架运行
    .NET CF 能不能快一点?
    jquery中文指导:15天学会jquery]]
    .NET CF开发的源代码级优化器(C#)(Alpha)
  • 原文地址:https://www.cnblogs.com/hsshy/p/4815060.html
Copyright © 2020-2023  润新知