Android开发-后端Model_Service

Android开发-后端Model_Service

[email protected]

2015年12月26日

1 目标:后台服务功能,不具备交互展示功能。

2 原理:Activity删除交互功能。

3 流程:创建服务,创建交互内容,调用服务。

3.1 创建服务:app->java右键-》new-》service-》Service。

3.2 创建服务后会自动重写onBind()绑定响应函数,这里需要重写onCreate()服务创建响应函数和onStartCommand()服务启动响应函数。

//ServiceWithoutIntent.java

package lee.com.demo;

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

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

    @Override
    public void onCreate() {
        super.onCreate();
       Log.d("ServiceWithoutIntent", "created.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, intstartId) {
       Log.d("ServiceWithoutIntent", "onStartCommand.");

        String info="intent="+intent.getStringExtra("xx")+",flag="+flags+",startId="+startId;
        Log.d("ServiceWithoutIntent",info);
        returnsuper.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communicationchannel to the service.
       Log.d("ServiceWithoutIntent","Binded..");
        return null;
    }
}

3.3 创建交互内容:intent

在页面中添加一个Button,设置响应函数为btnClick(),在其中设置intent和启动服务。

        Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);

       i.putExtra("xx","xx123");

3.4 调用服务:startService()

startService(i);

3.5 示例

//结果:点击按钮后在logcat中出现以下信息

01-16 17:59:29.32520378-20378/lee.com.demo D/ServiceWithoutIntent: onStartCommand.

01-16 17:59:29.32520378-20378/lee.com.demo D/ServiceWithoutIntent: intent=xx123,flag=0,startId=1

//ServiceWithoutIntent.java

package lee.com.demo;

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

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

    @Override
    public void onCreate() {
        super.onCreate();
       Log.d("ServiceWithoutIntent", "created.");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, intstartId) {
       Log.d("ServiceWithoutIntent", "onStartCommand.");

        String info="intent="+intent.getStringExtra("xx")+",flag="+flags+",startId="+startId;
       Log.d("ServiceWithoutIntent",info);
        returnsuper.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communicationchannel to the service.
       Log.d("ServiceWithoutIntent","Binded..");
        return null;
    }
}

//AndroidManifest.xml


    package="lee.com.demo" >

           android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:supportsRtl="true"
       android:theme="@style/AppTheme" >
                    android:name=".MainActivity"
           android:label="@string/app_name"
           android:theme="@style/AppTheme.NoActionBar" >
           
               

               
           

       

                   android:name=".ServiceWithoutIntent"
           android:enabled="true"
           android:exported="true" >
       
   

//activity_main.xml


   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"
   android:layout_height="match_parent"android:fitsSystemWindows="true"
   tools:context=".MainActivity"
    android:id="@+id/main">

           android:layout_width="match_parent"android:theme="@style/AppTheme.AppBarOverlay">

                    android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"
           android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />

   

   

           android:layout_width="wrap_content"android:layout_height="wrap_content"
       android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email"/>

//content_main.xml


    xmlns:tools="http://schemas.android.com/tools"
   xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"
   android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin"
   app:layout_behavior="@string/appbar_scrolling_view_behavior"
   tools:showIn="@layout/activity_main" tools:context=".MainActivity"
   android:id="@+id/ContentMainLayout">

           android:layout_height="wrap_content"
       android:id="@+id/textView" />

            android:layout_width="wrap_content"
       android:layout_height="wrap_content"
        android:text="NewButton"
       android:id="@+id/button"
       android:layout_below="@+id/textView"
       android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
       android:layout_marginTop="140dp"
        android:onClick="btnClick"
        />

//MainActivity.java

package lee.com.demo;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(BundlesavedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab =(FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(newView.OnClickListener() {
            @Override
            public void onClick(Viewview) {
                Snackbar.make(view,"Replace with your own action", Snackbar.LENGTH_LONG)
                       .setAction("Action", null).show();
            }
        });
    }

    @Override
    public booleanonCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this addsitems to the action bar if it is present.
       getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItemitem) {
        // Handle action bar item clickshere. The action bar will
        // automatically handle clicks onthe Home/Up button, so long
        // as you specify a parentactivity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspectionSimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        returnsuper.onOptionsItemSelected(item);
    }

    public void btnClick(View v){
        Log.d("MainActivity", "xxButton click");
        Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
       i.putExtra("xx","xx123");
        startService(i);
    }

}

4 方法:前后台通信Intent,Binder,Connection

服务在启动时会调用onCreate()响应函数。服务关闭时会调用onDestroy()响应函数。

4.1 开启服务:使用startService()/stopService()单纯的调用服务,并传递Intent作为单次通信数据。

服务可以监听onStartCommand()监听startStartService()。

4.2 绑定服务:使用bindService()/unbindService()调用服务,建立调用方和服务之间连接ServiceConnection,使用Binder进行实时通信。

ServiceConnection可以监听服务的连接、断开状态。

        ServiceConnection conn = newServiceConnection() {
            @Override
            public voidonServiceConnected(ComponentName name, IBinder service) {
               Log.d("conn","onServiceConnected="+name+","+service.toString());
                ServiceWithoutIntent.MyBindermyBinder = (ServiceWithoutIntent.MyBinder)service;
                Log.d("conn","count=" + myBinder.getCount());
                if(null==binder) {
                    binder=myBinder;
                }
            }

            @Override
            public voidonServiceDisconnected(ComponentName name) {
               Log.d("conn","onServiceDisconnected="+name);
            }
        };

Binder将进行实时通信,需要自定义通信方法。

            Log.d("conn", "count=" +binder.getCount());
                                binder.setCount(binder.getCount()+1);

服务可以监听onBind()监听bindService(),连接可以监听onServiceConnected()监听连接建立,onServiceDisonnected()监听连接的意外断开。

在onBind()中要返回一个IBinder对象,一般使用内部类扩展Binder类,定义通信协议。

    public class MyBinder extends Binder {
        private int count=5;
        public int getCount(){
            return count;
        }
        public void setCount(int count){
            this.count=count;
        }
    }

4.3 区别:startService(),只进行服务调用,无其它作用。bindService()调用服务的同时建立1:1关系,如果主动调用unbindService()将会同时关闭调用方和服务。

4.4 示例

//结果:点击按钮后在logcat中出现以下信息

01-16 22:56:42.62325556-25556/lee.com.demo D/MainActivity: xx Button click

01-16 22:56:42.62925556-25556/lee.com.demo D/ServiceWithoutIntent: created.

01-16 22:56:42.62925556-25556/lee.com.demo D/ServiceWithoutInten2: Binded.

01-16 22:56:42.62925556-25556/lee.com.demo D/ServiceWithoutIntent2: intent=xx123

01-16 22:56:42.63225556-25556/lee.com.demo D/conn:onServiceConnected=ComponentInfo{lee.com.demo/lee.com.demo.ServiceWithoutIntent},lee.com.demo.ServiceWithoutIntent$MyBinder@59670e1

01-16 22:56:42.63225556-25556/lee.com.demo D/conn: count=5

//ServiceWithoutIntent.java

package lee.com.demo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

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

    @Override
    public void onCreate() {
        super.onCreate();
       Log.d("ServiceWithoutIntent", "created.");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
       Log.d("ServiceWithoutIntent","Destory");
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communicationchannel to the service.
       Log.d("ServiceWithoutInten2","Binded.");
       Log.d("ServiceWithoutIntent2","intent="+intent.getStringExtra("xx"));
        return new MyBinder();
    }

    public class MyBinder extends Binder {
        private int count=5;
        public int getCount(){
            return count;
        }
        public void setCount(int count){
            this.count=count;
        }
    }
}

//AndroidManifest.xml


    package="lee.com.demo" >

           android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:supportsRtl="true"
       android:theme="@style/AppTheme" >
                    android:name=".MainActivity"
           android:label="@string/app_name"
           android:theme="@style/AppTheme.NoActionBar" >
           
               

               
           

       

                   android:name=".ServiceWithoutIntent"
           android:enabled="true"
           android:exported="true" >
       
   

//activity_main.xml


   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"
   android:layout_height="match_parent"android:fitsSystemWindows="true"
   tools:context=".MainActivity"
    android:id="@+id/main">

           android:layout_width="match_parent"android:theme="@style/AppTheme.AppBarOverlay">

                   android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
           android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" />

   

   

           android:layout_width="wrap_content"android:layout_height="wrap_content"
       android:layout_gravity="bottom|end"android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email"/>

//content_main.xml


   xmlns:tools="http://schemas.android.com/tools"
   xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"
   android:layout_height="match_parent"android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin"
   app:layout_behavior="@string/appbar_scrolling_view_behavior"
   tools:showIn="@layout/activity_main"tools:context=".MainActivity"
   android:id="@+id/ContentMainLayout">

           android:layout_height="wrap_content"
       android:id="@+id/textView" />

            android:layout_width="wrap_content"
       android:layout_height="wrap_content"
        android:text="NewButton"
       android:id="@+id/button"
       android:layout_below="@+id/textView"
       android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
       android:layout_marginTop="140dp"
        android:onClick="btnClick"
        />

//MainActivity.java

package lee.com.demo;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(BundlesavedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab =(FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(newView.OnClickListener() {
            @Override
            public void onClick(Viewview) {
                Snackbar.make(view,"Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action",null).show();
            }
        });
    }

    @Override
    public booleanonCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this addsitems to the action bar if it is present.
       getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public booleanonOptionsItemSelected(MenuItem item) {
        // Handle action bar item clickshere. The action bar will
        // automatically handle clicks onthe Home/Up button, so long
        // as you specify a parentactivity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspectionSimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private ServiceWithoutIntent.MyBinder binder = null;
    public void btnClick(View v){
        Log.d("MainActivity","xx Button click");
        Intent i=newIntent(MainActivity.this,ServiceWithoutIntent.class);
       i.putExtra("xx","xx123");
        ServiceConnection conn = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name,IBinder service) {
               Log.d("conn","onServiceConnected="+name+","+service.toString());
               ServiceWithoutIntent.MyBinder myBinder =(ServiceWithoutIntent.MyBinder)service;
                Log.d("conn","count=" + myBinder.getCount());
                if(null==binder) {
                    binder=myBinder;
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
               Log.d("conn","onServiceDisconnected="+name);
            }
        };
        if(null==binder) {
            bindService(i, conn, BIND_AUTO_CREATE);
        }
//        else if(7==binder.getCount()){
//            unbindService(conn);
//        }
        else{
            Log.d("conn", "count=" +binder.getCount());
           binder.setCount(binder.getCount()+1);

        }

    }
}

4.5 多线程服务IntentService

Service的增强版本,开启单独的线程工作。

Service是在主线程中工作,耗时操作会阻塞进程。

你可能感兴趣的:(Android,android,Activity,Intent,Service,AndroidStudio)