服务( 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 机制。
原文:http://my.oschina.net/u/2480757/blog/517864