转载请注明出处:http://blog.csdn.net/krislight/article

Service可以看作一个后台服务,但并非是开启另外的线程,Service还是在主线程中运行.所以需避免耗时操作。

如果Service還未啟動,調用startService方法會call Service的onCreate()方法,如果已經啟動會call Service的

onStartCommand()方法,在onStartCommand()方法最後會返回一個int值代表Service重啟后的行為,該int值含義有

以下幾種:

Table 1. Restart options

Option

Description

Service.START_STICKY

Service is restarted if it gets terminated. Intent data passed to the onStartCommand method is null. Used for services which manages their own state and do not depend on the Intent data.

Service.START_NOT_STICKY

Service is not restarted. Used for services which are periodically triggered anyway. The service is only restarted if the runtime has pending startService() calls since the service termination.

Service.START_REDELIVER_INTENT

Similar to Service.START_STICKY but the original Intent is re-delivered to the onStartCommand method.

通過Intent.getFlags()方法可以判斷Service是否重啟過,返回START_FLAG_REDELIVERYSTART_FLAG_RETRY代表Service已經重啟過了。

通過stopService()stopSelf()來停止Service

如果一個Activity想和Service之間交互通信,使用bindService()來啟動Service

可以指定android:process屬性將service運行到另一個單獨的進程,如果屬性前面有分號如

android:process =”:remote”代表該Service針對自身的應用程序私有,如果沒有分號如

android:process =”remote”代表該Service是共享進程,可以被其他應用程序使用。

很少指定Service運行在單獨運行在自己的進程,除非你希望將Service與其他應用程序共享。

IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,

对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的

worker thread中处理,不会阻塞应用程序的主线程.

使用IntentService下載文件實例:

①在Acitivity中啟動Service

public class DownloadService extends IntentService {
private int result = Activity.RESULT_CANCELED;
public static final String URL = "urlpath";
public static final String FILENAME = "filename";
public static final String FILEPATH = "filepath";
public static final String RESULT = "result";
public static final String NOTIFICATION = "com.example.android.service.receiver"; public DownloadService() {
super("DownloadService");
} // will be called asynchronously by Android
@Override
protected void onHandleIntent(Intent intent) {
String urlPath = intent.getStringExtra(URL);
String fileName = intent.getStringExtra(FILENAME);
File output = new File(Environment.getExternalStorageDirectory(),
fileName);
if (output.exists()) {
output.delete();
} InputStream stream = null;
FileOutputStream fos = null;
try { URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new FileOutputStream(output.getPath());
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
// successfully finished
result = Activity.RESULT_OK; } catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
publishResults(output.getAbsolutePath(), result);
} private void publishResults(String outputPath, int result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(FILEPATH, outputPath);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}

在XML配置文件中申請權限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

註冊Service

<service android:name="com.example.android.service.DownloadService" ></service>

佈局文件main_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Download" /> <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status: " />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Not started" />
</LinearLayout>
</LinearLayout>

主頁面:

public class MainActivity extends Activity {
private TextView textView;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
String string = bundle.getString(DownloadService.FILEPATH);
int resultCode = bundle.getInt(DownloadService.RESULT);
if (resultCode == RESULT_OK) {
Toast.makeText(MainActivity.this,
"Download complete. Download URI: " + string,
Toast.LENGTH_LONG).show();
textView.setText("Download done");
} else {
Toast.makeText(MainActivity.this, "Download failed",
Toast.LENGTH_LONG).show();
textView.setText("Download failed");
}
}
}
}; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.status);
} @Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(DownloadService.NOTIFICATION));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
} public void onClick(View view) {
Intent intent = new Intent(this, DownloadService.class);
// add infos for the service which file to download and where to store
intent.putExtra(DownloadService.FILENAME, "index.html");
intent.putExtra(DownloadService.URL,
"http://www.baidu.com/index.html");
startService(intent);
textView.setText("Service started");
}
}

這裡Activity與Service交互是通過Activity註冊一個BroadCastReceiver來監聽廣播,啟動Service后,一旦Service完成任務發送廣播,BroadCastReceiver監聽到廣播進行相應的處理。

再介紹一個例子讓Activity綁定到運作中的Service,這個Service在開機后自動運行,并模擬抓取數據

先建一個Service:

public class LocalWordService extends Service {
private final IBinder mBinder = new MyBinder();
private ArrayList<String> list = new ArrayList<String>();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Random random = new Random();
if (random.nextBoolean()) {
list.add("Linux");
}
if (random.nextBoolean()) {
list.add("Android");
}
if (random.nextBoolean()) {
list.add("iPhone");
}
if (random.nextBoolean()) {
list.add("Windows7");
}
if (list.size() >= 20) {
list.remove(0);
}
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
LocalWordService getService() {
return LocalWordService.this;
}
}
public List<String> getWordList() {
return list;
}
}

建立一個監聽開機啟動的廣播接收器,該接收器每隔30秒發送啟動Service的廣播:

public class MyScheduleReceiver extends BroadcastReceiver {
// restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 30;
@Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// start 30 seconds after boot completed
cal.add(Calendar.SECOND, 30);
// fetch every 30 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
// service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
// REPEAT_TIME, pending);
}
}

啟動Service的接收器:

public class MyStartServiceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, LocalWordService.class);
context.startService(service);
}
}

佈局文件mainLayout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Update" >
</Button>
<ListView
android:id="@id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>

主頁面:

public class MainActivity extends ListActivity {
private LocalWordService s;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wordList = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
wordList);
setListAdapter(adapter);
} @Override
protected void onResume() {
super.onResume();
Intent intent= new Intent(this, LocalWordService.class);
bindService(intent, mConnection,
Context.BIND_AUTO_CREATE);
} @Override
protected void onPause() {
super.onPause();
unbindService(mConnection);
} private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className,
IBinder binder) {
LocalWordService.MyBinder b = (LocalWordService.MyBinder) binder;
s = b.getService();
Toast.makeText(MainActivity.this, "Connected", Toast.LENGTH_SHORT)
.show();
} public void onServiceDisconnected(ComponentName className) {
s = null;
}
};
private ArrayAdapter<String> adapter;
private List<String> wordList; public void onClick(View view) {
if (s != null) {
Toast.makeText(this, "Number of elements" + s.getWordList().size(),
Toast.LENGTH_SHORT).show();
wordList.clear();
wordList.addAll(s.getWordList());
adapter.notifyDataSetChanged();
}
}
}

Service知识点总结的更多相关文章

  1. 关于Android的Service知识点,你知道吗?

    目录 学习Service相关知识点: 概述: Service生命周期: Service的基本用法: 服务. 问:达叔,今日工作累吗? 答:累啊,那么问你,你知道Android中的 Service(服务 ...

  2. 23 个重难点突破,带你吃透 Service 知识点「长达 1W+ 字」

    前言 学 Android 有一段时间了,想必不少人也和我一样,平时经常东学西凑,感觉知识点有些凌乱难成体系.所以趁着这几天忙里偷闲,把学的东西归纳下,捋捋思路. 这篇文章主要针对 Service 相关 ...

  3. 【转】23 个安卓重难点突破,带你吃透 Service 知识点「长达 1W+ 字」

    前言 学 Android 有一段时间了,想必不少人也和我一样,平时经常东学西凑,感觉知识点有些凌乱难成体系.所以趁着这几天忙里偷闲,把学的东西归纳下,捋捋思路. 这篇文章主要针对 Service 相关 ...

  4. Android:Service的注意点以及一些知识点

    1.自己练习service的start()方法开启一个service服务的时候,不管怎么开启按钮,就是开启不了service服务,控制台也没有报错信息, app不闪退,代码就那么几行.找了好久找不出来 ...

  5. Android Service用法知识点的讲解

    Android Service 学习Service相关知识点: android service 的基础知识,生命周期,service分类,运行地点(本地服务,远程服务),运行类型(前台服务,后台服务) ...

  6. 这个知识点不错,,学习一下先。。。无状态服务(stateless service)(转)

    这样的应用,显得高级一些哟~~:) +================== http://kyfxbl.iteye.com/blog/1831869 ========================= ...

  7. 云服务器ECS(Elastic Compute Service),知识点

    资料 网址 什么是云服务器ECS https://help.aliyun.com/document_detail/25367.html?spm=a2c4g.11186623.6.544.4e1e376 ...

  8. 关系型数据库 RDS(Relational Database Service),知识点

    资料 网址 官方介绍 https://help.aliyun.com/document_detail/26092.html?spm=5176.2020520104.0.0.2b4b1450yqd1gg ...

  9. 对象存储服务 OSS(Object Storage Service),知识点(待补充上仓库代码)

    资料 网址 官方文档 https://help.aliyun.com/product/31815.html?spm=a2c4g.11186623.3.1.3e1459669xRokl OSS Brow ...

随机推荐

  1. js验证

    验证短日期(2007-06-05) function strDateTime(str) {    var r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1 ...

  2. (转) ASP.NET反射

    原文:http://www.cnblogs.com/zizo/p/3509895.html 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何 ...

  3. js 函数命名

    1 函数命名可以使用匿名: var f=function(x){return x*2;} 2 可以使用变量: function double(x){return x*2;} 二者区别:后者会绑定到与其 ...

  4. js获得文件根目录

    function getRootPath(){ //获取当前网址,如: http://localhost:8083/proj/meun.jsp var curWwwPath = window.docu ...

  5. #ifndef#define#endif的用法

    在网上看到了感觉作者总结得很好,作者辛苦了! #ifndef#define#endif的用法 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都 ...

  6. WPFX名称空间

    1:x名称空间里的成员是专门写给xaml编译器看,用来引导xaml编译器把xaml代码编译成CLR代码的.(x仅仅是xaml的首字母). 2:attribute 是语言层面的东西,是给编译器看的,Pr ...

  7. RAC分解步骤之一,在oracle linux 4u4上安装oracle 10.2.0.1.0操作日志

    练习oracle的rac组建过程,第一步,先练习4u4上安装oracle 10.2.0.1.0.直接安装rac,有些难度.从简单的做起.总RAC步骤,参照小布老师的RAC组建. 1. 启动vc,登陆v ...

  8. redis基本数据类型【3】-List类型

    列表类型采用双向链表实现的,借助列表类型redis还可以作为队列使用,一个列表类型key最多能容纳2^32-1个元素 1.向列表两端增加元素 #向左边增加元素,返回增加后列表的长度 lpush key ...

  9. 在Windows下用gSoap实现简单加法实例

    实现一个简单的a+b程序,在服务器端写一个程序,里面包含了a+b的函数,然后通过客户端代码向其发送两个数字,在服务器运算得到结果返回给客户端显示出来. 1.在gSoap的官网上下载文件夹,本人的版本是 ...

  10. 九度OJ 1516 调整数组顺序使奇数位于偶数前面 -- 归并排序

    题目地址:http://ac.jobdu.com/problem.php?pid=1516 题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的 ...