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

Android Service 后台服务之本地服务

2016-05-07 15:53 676 查看
Service是Android系统的服务组件,适用于开发没有用户界面且长时间在后台运行的功能

-

Service简介

因为手机硬件性能和屏幕尺寸的限制,通常Android系统仅允许一个应用程序处于激活状态并显示在手机屏幕上,而暂停其他处于未激活状态的程序。
因此,Android系统需要一种后台服务机制,允许在没有用户界面的情况下,使程序能够长时间在后台运行,实现应用程序的后台服务功能。

在实际应用中,有很多应用需要使用Service,比如MP3播放器要求在关闭播放器界面后,仍然能够后台保持音乐持续播放。


下面我将Service基础知识简单归纳为以下6点:

- 1.Service适用于什么功能?

Service使用于无须用户干预,且有规则地运行或长期运行的后台共功能。


- 2.Service的特点

Service没有用户界面,相比于其他应用程序更加有利于降低系统资源的消耗。

Service比Activity具有更高优先级,在资源紧张时,Service不会被Android系统优先终止。

即使Service被系统终止,在系统资源恢复后Service也将自动回复运行状态,因此可以认为Service是在系统中可以稳定长期运行的组件。


- 3.Service的用处

1.实现后台服务功能

2.可用于进程间通信


- 4.Service的生命周期



完整的生命周期从onCreate()开始到onDestroy()结束,在onCreate()中完成Service的初始化工作,在onDestroy()中释放所有占用的资源。
可以粗略的认为活动生命周期以onDestroy()标志结束。


- 5.通过启动方式使用Service

实现

通过Context.startService()启动Service,通过Context.stopService()停止Seivice。
Context指其他组件,因此Service一定是由其它组件启动的,但停止过程可以通过其他组件或自身完成。


特点

启动Service的组件无法获取Service的对象实例,因此也无法调用Service中的任何函数,
也不能获取Service中的任何状态和数据信息。所以以启动方式的Service需要具备自管理的能力。


- 6.通过绑定方式使用Service

实现

在其他组件中调用Context.bindService()建立服务连接,调用Context.unbindService()停止服务连接。
如果在绑定过程中Service未启动,Context.bindService()会自动启动Service。


特点

其他组件可以获取Service的实例对象并调用Service中的函数,可以获取Service中的状态和数据信息。
同一个Service可以和被多个组件绑定服务连接,即同一个Service可以同时为多个组件服务。


本地服务

概念: 本地服务的调用者和服务都在同一个程序中,是不需要跨进程就可以实现服务的调用。

以下为一个设计到本地服务的简单Demo,包括启动方式和绑定方式的使用。主界面如图:



项目结构如图:



RandomService.java(启动方式)完整代码:

package com.example.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

/**
* Created by yinghao on 2016/5/6.
*/
public class RandomService extends Service {

/*
onStartCommand 取代 onStart
但在 super.onStartCommand(intent, flags, startId); 方法中调用了 onStart()方法(为了兼容)
*/

private Thread workThread;
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "调用onCreate()", Toast.LENGTH_SHORT).show();
workThread = new Thread(null, backgroundWork, "workThread");
}

@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(RandomService.this, "onStart()", Toast.LENGTH_SHORT).show();
if (!workThread.isAlive()) {
workThread.start();
}

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(RandomService.this, "onStartCommand()", Toast.LENGTH_SHORT).show();

return super.onStartCommand(intent, flags, startId);

}

@Override
public void onDestroy() {
Toast.makeText(this, "调用onDestroy()", Toast.LENGTH_SHORT).show();
workThread.interrupt();
super.onDestroy();

}

private Runnable backgroundWork = new Runnable() {
@Override
public void run() {
try {
while (!Thread.interrupted()) {
double randomDouble = Math.random();
MainActivity.UpdateGUI(randomDouble);

Thread.sleep(1000);

}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};

/**
*  Service 被绑定后调用的函数,能够返回Service对象实例
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}


MathService.java(绑定方式)完整代码:

package com.example.servicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;

/**
* Created by yinghao on 2016/5/6.
*/
public class MathService extends Service {

/**
*   以绑定形式使用此Service 获取Service实例
*/
private final IBinder mBinder = new LocalBinder();
public class  LocalBinder extends Binder{
MathService getService() {
return MathService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(MathService.this, "本地绑定", Toast.LENGTH_SHORT).show();
return mBinder;
}

@Override
public boolean onUnbind(Intent intent) {
Toast.makeText(MathService.this, "取消本地绑定:MathService", Toast.LENGTH_SHORT).show();
return super.onUnbind(intent);
}

public long add(long a, long b) {
return a + b;
}
}


MainActivity.java完整代码:

package com.example.servicedemo;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.example.simplerandomservicedemo.R;

public class MainActivity extends AppCompatActivity {

private Button mStartButton;
private Button mStopButton;
private static TextView mLabelTextVie;
private static Handler handler = new Handler();
private static double random;
/**
*   Handler 将Runnable对象 传递给 界面线程的队列中
*   使其能更新UI
*/
public static void UpdateGUI(double refreshDouble) {
random = refreshDouble;
handler.post(RefreshLable);
}
public static Runnable RefreshLable = new Runnable() {
@Override
public void run() {
mLabelTextVie.setText(String.valueOf(random));
}
};

private MathService mathService;
private boolean isBound = false;
private TextView sum;
private Button bindButton;
private Button unbindButton;
private Button addButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* Handler
*/
final Intent intent = new Intent(this,RandomService.class);
mStartButton = (Button) findViewById(R.id.start);
mStopButton = (Button) findViewById(R.id.stop);
mLabelTextVie = (TextView) findViewById(R.id.tv_label);
mStartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(intent);

}
});
mStopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopService(intent);
}
});
/**
* bind Service
*/
sum = (TextView) findViewById(R.id.tv_result);
bindButton = (Button) findViewById(R.id.bind);
unbindButton = (Button) findViewById(R.id.unbind);
addButton = (Button) findViewById(R.id.add);

final Intent serviceIntent = new Intent(MainActivity.this, MathService.class);

bindButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isBound) {
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
isBound = true;
}
}
});
unbindButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isBound) {
unbindService(mConnection);
//若把上面取消绑定改为下面的关闭Service  则无法再次绑定成功
//                    stopService(serviceIntent);
mathService = null;
isBound = false;
}
}
});
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mathService == null) {
sum.setText("未绑定服务");
return;
}
long a = Math.round(Math.random() * 100);
long b = Math.round(Math.random() * 100);
long result = mathService.add(a, b);
String msg = String.valueOf(a)+"+"+String.valueOf(b)+"="+result;
sum.setText(msg);

}
});

}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mathService = ((MathService.LocalBinder) service).getService();
}

@Override
public void onServiceDisconnected(ComponentName name) {
mathService = null;
}
};

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: