如何使用IntentService-實作

如何使用IntentService-實作

如何使用IntentService中解說了怎麼使用IntentService,
所以現在寫一個範例來示範怎麼使用它。

首先宣告2個Button來代表送出Task1跟Task2,
接著用一個TextView來呈現送出Task的結果。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="example.givemepass.intentservicedemo.MainActivity">
    <Button
        android:id="@+id/send_task1"
        android:text="send task 1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:layout_toRightOf="@id/send_task1"
        android:id="@+id/send_task2"
        android:text="send task 2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/result"
        android:layout_below="@id/send_task1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

接著宣告主程式的部分

public class MainActivity extends AppCompatActivity {

    private Button task1;
    private Button task2;
    private TextView result;
    private ResultReceiver receiver;
    private StringBuffer stringBuffer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }
    private void initData(){
        stringBuffer = new StringBuffer();
        receiver = new ResultReceiver(new Handler()){
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                if(resultCode == Constant.RESULT_CODE) {
                    String returnStr = resultData.getString(Constant.RETURN_TASK);
                    if(returnStr != null) {
                        stringBuffer.append(returnStr + "\n");
                        result.setText(stringBuffer);
                    }
                }
            }
        };
    }
    private void initView(){
        task1 = (Button) findViewById(R.id.send_task1);
        task2 = (Button) findViewById(R.id.send_task2);
        result = (TextView) findViewById(R.id.result);
        task1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MyIntentService.class);
                intent.putExtra(Constant.FLAG_TASK, Constant.TASK1);
                intent.putExtra(Constant.FLAG_RECEIVER, receiver);
                startService(intent);
            }
        });
        task2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, MyIntentService.class);
                intent.putExtra(Constant.FLAG_TASK, Constant.TASK2);
                intent.putExtra(Constant.FLAG_RECEIVER, receiver);
                startService(intent);
            }
        });
    }
}

首先可以看到定義一個Receiver, 用來回傳Service所執行的結果。

receiver = new ResultReceiver(new Handler()){
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        if(resultCode == Constant.RESULT_CODE) {
            String returnStr = resultData.getString(Constant.RETURN_TASK);
            if(returnStr != null) {
                stringBuffer.append(returnStr + "\n");
                result.setText(stringBuffer);
            }
        }
    }
};

接著利用Task1 Button跟Task2 Button傳送任務到Service那邊進行處理

task1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, MyIntentService.class);
        intent.putExtra(Constant.FLAG_TASK, Constant.TASK1);
        intent.putExtra(Constant.FLAG_RECEIVER, receiver);
        startService(intent);
    }
});
task2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, MyIntentService.class);
        intent.putExtra(Constant.FLAG_TASK, Constant.TASK2);
        intent.putExtra(Constant.FLAG_RECEIVER, receiver);
        startService(intent);
    }
});

IntentService的部分

public class MyIntentService extends IntentService {

    public MyIntentService() {
        super(Constant.SERVICE_NAME);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        int taskFlag = intent.getIntExtra(Constant.FLAG_TASK, 1);
        ResultReceiver receiver = intent.getParcelableExtra(Constant.FLAG_RECEIVER);
        int rand = (int)(Math.random()*3 + 1);
        try {
            Thread.sleep(rand * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(taskFlag == 1){
            Bundle bundle = new Bundle();
            bundle.putString(Constant.RETURN_TASK, Constant.TASK1_MSG);
            receiver.send(Constant.RESULT_CODE, bundle);
        } else{
            Bundle bundle = new Bundle();
            bundle.putString(Constant.RETURN_TASK, Constant.TASK2_MSG);
            receiver.send(Constant.RESULT_CODE, bundle);
        }
    }
}

在Service部分利用Thread.sleep的方法隨機讓他停頓, 模擬長任務的做法,
判斷是從Task1或者是從Task2送過來的, 再將結果透過Receiver送出回去。

Constant參數

public class Constant {
    public static final String SERVICE_NAME = "intent service";
    public static final String FLAG_TASK = "task";
    public static final String FLAG_RECEIVER = "receiver";
    public static final int TASK1 = 1;
    public static final int TASK2 = 2;
    public static final int RESULT_CODE = 100;
    public static final String RETURN_TASK = "return_task";
    public static final String TASK1_MSG = "task 1 is done.";
    public static final String TASK2_MSG = "task 2 is done.";
}

可從下面看到結果, 每當按下一次Button就是送出一個Task,
可以看到Service按照按下的順序執行每一個任務。

程式碼