服务( Service)是 Android 中实现程序后台运行的解决方案,它非常适合用于去执行那
些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,即使
当程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。
不过需要注意的是,服务并不是运行在一个独立的进程当中的,而是依赖于创建服务
时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停
止运行。
另外,也不要被服务的后台概念所迷惑, 实际上服务并不会自动开启线程,所有的代码
都是默认运行在主线程当中的。也就是说,我们需要在服务的内部手动创建。
多线程更新UI:
public class MainActivity extends Activity implements OnClickListener {
public static final int UPDATE_TEXT = 1;
private TextView text;
private Button changeText;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_TEXT:
//
在这里可以进行
UI
操作
text.setText("Nice to meet you");
break;
default:
break;
}
}
};
……
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.change_text:
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message); //
将
Message
对象发送出去
}
}).start();
break;
default:
break;
}
}
}
Android 中的异步消息处理主要由四个部分组成, Message、 Handler、 MessageQueue 和
Looper。
1. Message
Message 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线
程之间交换数据。上一小节中我们使用到了 Message 的 what 字段,除此之外还可以使
用 arg1 和 arg2 字段来携带一些整型数据,使用 obj 字段携带一个 Object 对象。
2. Handler
Handler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消
息一般是使用 Handler 的 sendMessage()方法,而发出的消息经过一系列地辗转处理后,
最终会传递到 Handler 的 handleMessage()方法中。
3. MessageQueue
MessageQueue 是消息队列的意思,它主要用于存放所有通过 Handler 发送的消息。
这部分消息会一直存在于消息队列中,等待被处理。每个线程中只会有一个 MessageQueue
对象。
4. Looper
Looper 是每个线程中的 MessageQueue 的管家,调用 Looper 的 loop()方法后,就会
进入到一个无限循环当中,然后每当发现 MessageQueue 中存在一条消息,就会将它取
//实现多线程并且显示进度条。
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
……
}
package com.example.downloadfile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.TextView;
public class DownloadFile extends Activity {
public static final String LOG_TAG = "test";
private ProgressDialog mProgressDialog;
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
File rootDir = Environment.getExternalStorageDirectory();
//定义要下载的文件名
public String fileName = "test.jpg";
public String fileURL = "https://lh4.googleusercontent.com/-HiJOyupc-tQ/TgnDx1_HDzI/AAAAAAAAAWo/DEeOtnRimak/s800/DSC04158.JPG";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = new TextView(this);
tv.setText("Android Download File With Progress Bar");
//检查下载目录是否存在
checkAndCreateDirectory("/mydownloads");
//执行asynctask
new DownloadFileAsync().execute(fileURL);
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
@Override
protected String doInBackground(String... aurl) {
try {
//连接地址
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
//计算文件长度
int lenghtOfFile = c.getContentLength();
FileOutputStream f = new FileOutputStream(new File(rootDir + "/my_downloads/", fileName));
InputStream in = c.getInputStream();
//下载的代码
byte[] buffer = new byte[1024];
int len1 = 0;
long total = 0;
while ((len1 = in.read(buffer)) > 0) {
total += len1; //total = total + len1
publishProgress("" + (int)((total*100)/lenghtOfFile));
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.d(LOG_TAG, e.getMessage());
}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d(LOG_TAG,progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String unused) {
//dismiss the dialog after the file was downloaded
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
public void checkAndCreateDirectory(String dirName){
File new_dir = new File( rootDir + dirName );
if( !new_dir.exists() ){
new_dir.mkdirs();
}
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS: //we set this to 0
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
}
活动的书写步骤:
1,写一个类,继承Service。复写onBind方法。
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
2, 在
AndroidManifest.xml 文件中进行注册。
<service android:name=".MyService" >
</service>
//3,启动和停止服务
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_service:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent); // 启动服务
break;
case R.id.stop_service:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); // 停止服务
break;
default:
break;
}
}
//4,实现各个的处理方法
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate executed");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService", "onStartCommand executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log. d("MyService", "onDestroy executed");
}
Android 中的定时任务一般有两种实现方式,一种是使用 Java API 里提供的 Timer 类,
一种是使用 Android 的 Alarm 机制。
Service的两种形式。
1,started service:基本概念,其它组件(例如activity)通过调用startservice()启动该service,拥有独立得生命周期,不依赖启动它的组件。
//1,绑定服务
Intent intent = new Intent();
intent.setClass(MainActivity.this, JikeService.class);
startService(intent);
//2,建立JikeService类。
public class JikeService extends Service {
private class ServiceThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for (int i = 0; i < 5; i++) {
System.out.println("当前的值:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//该服务完成后,自己停止服务
JikeService.this.stopSelf();
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println("onCreate...");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
ServiceThread st = new ServiceThread();
st.start();
System.out.println("onStartCommand...");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.out.println("onDestory");
}
}
2,BoundService 其它组件为了与service建立一个长时间的连接,通过调用bindService启动并绑定该service,并能预支交互,生命周期依赖绑定他的组件,一旦组件取消绑定,则消亡。