您的位置:首页 > 移动开发 > Android开发

Android开发-后端Model_Service

2016-01-18 16:08 417 查看
Android开发-后端Model_Service
sf2gis@163.com
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

<?xmlversion="1.0" encoding="utf-8"?>

<manifestxmlns:android="http://schemas.android.com/apk/res/android"

    package="lee.com.demo" >

    <application

       android:allowBackup="true"

       android:icon="@mipmap/ic_launcher"

       android:label="@string/app_name"

       android:supportsRtl="true"

       android:theme="@style/AppTheme" >

        <activity

            android:name=".MainActivity"

           android:label="@string/app_name"

           android:theme="@style/AppTheme.NoActionBar" >

            <intent-filter>

                <actionandroid:name="android.intent.action.MAIN" />

                <categoryandroid:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <service

           android:name=".ServiceWithoutIntent"

           android:enabled="true"

           android:exported="true" >

        </service>

    </application>

</manifest>

//activity_main.xml

<?xmlversion="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout

   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.support.design.widget.AppBarLayoutandroid:layout_height="wrap_content"

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

       <android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"

            android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"

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

   </android.support.design.widget.AppBarLayout>

    <includelayout="@layout/content_main" />

   <android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"

       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"/>

</android.support.design.widget.CoordinatorLayout>

//content_main.xml

<?xmlversion="1.0" encoding="utf-8"?>

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    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">

    <TextView android:text="HelloWorld,Android!" android:layout_width="wrap_content"

       android:layout_height="wrap_content"

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

    <Button

        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"

        />

</RelativeLayout>

//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

<?xmlversion="1.0" encoding="utf-8"?>

<manifestxmlns:android="http://schemas.android.com/apk/res/android"

    package="lee.com.demo" >

   <application

       android:allowBackup="true"

       android:icon="@mipmap/ic_launcher"

       android:label="@string/app_name"

       android:supportsRtl="true"

       android:theme="@style/AppTheme" >

        <activity

            android:name=".MainActivity"

           android:label="@string/app_name"

           android:theme="@style/AppTheme.NoActionBar" >

            <intent-filter>

                <actionandroid:name="android.intent.action.MAIN" />

                <categoryandroid:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <service

           android:name=".ServiceWithoutIntent"

           android:enabled="true"

           android:exported="true" >

        </service>

    </application>

</manifest>

//activity_main.xml

<?xmlversion="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout

   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.support.design.widget.AppBarLayoutandroid:layout_height="wrap_content"

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

       <android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"

           android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"

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

   </android.support.design.widget.AppBarLayout>

    <includelayout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"

       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"/>

</android.support.design.widget.CoordinatorLayout>

//content_main.xml

<?xmlversion="1.0" encoding="utf-8"?>

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

   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">

    <TextView android:text="HelloWorld,Android!" android:layout_width="wrap_content"

       android:layout_height="wrap_content"

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

    <Button

        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"

        />

</RelativeLayout>

//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是在主线程中工作,耗时操作会阻塞进程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息