說到Android的IPC(Inter-Process Conmmunication)首先想到的就是Handler和Looper,Handler用於多進程之間的通信和數據交換,將各進程之間通信的數據Message放置到Message Queue裡,而Looper用於創建各進程自身的message queue,然後在適當的時候分發給相應的進程。
我們知道在Android中,每一個UI線程是一個主線程(Main Thread),Android為每一個主線程維護一個Message Queue,當用戶需要長時間的背景線程操作的時候,需要create自己的new thread,這樣的new thread是沒有自己的message queue的,只能共享主線程的message queue並且將所做的運算結果和數據通過Handler發送到主線程的message queue裡,被主線程共享。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ProgressBar
android:id="@+id/ProgressBar01"
android:layout_width="150dip"
android:layout_height="wrap_content"
>
</ProgressBar>
</LinearLayout>
這個xml文件創建了一個progressbar,並且將style設置成水平,
1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="waterlife.ipc.demo"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".IPCConmunication"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
為了訪問網絡,需要在manifest file裡設置access internet的permission,
<uses-permission android:name="android.permission.INTERNET" />
package waterlife.ipc.demo;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.widget.ProgressBar;
public class IPCConmunication extends Activity {
static ProgressBar pb;
final int UPDATE_PROGRESS_BAR = 1000;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pb = (ProgressBar)findViewById(R.id.ProgressBar01);
Download dl = new Download();
new Thread(dl).start();
}
Handler mHandle = new Handler()
{
public void handleMessage(Message msg)
{
switch(msg.what)
{
case UPDATE_PROGRESS_BAR:
pb.setProgress(msg.arg1);
break;
default:
break;
}
}
};
class Download implements Runnable
{
@Override
public void run() {
int totalSize = 0;
InputStream recevier = null;
try {
URL myUrl = new URL("http://bbs.nju.edu.cn");
URLConnection urlConn = myUrl.openConnection();
totalSize = urlConn.getContentLength();
recevier = urlConn.getInputStream();
byte[] b =new byte[256];
int length = 0;
length += recevier.read(b);
while(length < totalSize)
{
Message msg = mHandle.obtainMessage(UPDATE_PROGRESS_BAR);
msg.arg1 = (int)(length*100/totalSize);
if(mHandle.hasMessages(UPDATE_PROGRESS_BAR))
{
mHandle.removeMessages(UPDATE_PROGRESS_BAR);
}
mHandle.sendMessage(msg);
length += recevier.read(b);
Thread.sleep(1000); //睡眠1S,這個方法是不值得推薦的,因為它會使線程獨占CPU,在以後的例子會使用更加有效的方法
}
recevier.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}