Android Service——活動和服務進行通信

服務是在活動裏啓動的,但是啓動了服務之後,活動與服務基本就沒什麼關係了,爲了能讓服務和活動的關係緊密一點,在這裏介紹一種利用廣播接收器的方式來使得服務和活動聯繫起來。
在這裏模擬下載的情況,利用一個進度條來使得服務和活動聯繫起來,然後佈局一個按鈕和一個進度條

利用廣播接收器來實現活動和服務的聯繫

 <Button
        android:id="@+id/button_startdown"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="開始下載"/>

    <ProgressBar
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_gravity="center_horizontal" />

然後在主活動中通過點擊事件來啓動服務

Intent intent=new Intent(getApplicationContext(),MyFirstService.class);
        startService(intent);

在Service類中的onStartCommand()方法中定義一個count計數模擬每秒下載百分之一,然後發送廣播

package com.example.administrator.myserviceapplication;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

/**
 * Created by Administrator on 2015/9/8.
 */
public class MyFirstService extends Service {
    private int count=0;
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("00000000000000000000000", "onCreate ");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("00000000000000000000000", "onStartCommand ");
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    count++;
                    if (count>100){
                        count=0;
                    }
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Intent intent=new Intent();
                    intent.setAction("com.downlowd.test");
                    intent.putExtra("count",count);
                    sendBroadcast(intent);
                }
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("00000000000000000000000", "onDestroy ");
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

最後在主活動中進行廣播接收器的註冊和處理

package com.example.administrator.myserviceapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

import static com.example.administrator.myserviceapplication.R.id.button_startdown;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button mButtonStartDown;
    private ProgressBar mProgressBar;
    private MyDownLoadReceiver mMyDownReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButtonStartDown= (Button) findViewById(button_startdown);
        mButtonStartDown.setOnClickListener(this);
        mProgressBar= (ProgressBar) findViewById(R.id.progressBar);
        //廣播接收器的註冊   動態註冊
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction("com.downlowd.test");
        mMyDownReceiver=new MyDownLoadReceiver();
        registerReceiver(mMyDownReceiver,intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //廣播接收器取消註冊

        unregisterReceiver(mMyDownReceiver);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){

            case R.id.button_startdown:
               start();
                break;
            default:
                break;
        }
    }

    private void start() {
        Intent intent=new Intent(getApplicationContext(),MyFirstService.class);

        startService(intent);
    }

    private void stop() {
        Intent intent=new Intent(getApplicationContext(),MyFirstService.class);
        stopService(intent);
    }
    class MyDownLoadReceiver extends BroadcastReceiver{
//廣播接收器接收廣播並進行處理
        @Override
        public void onReceive(Context context, Intent intent) {
            int count=intent.getIntExtra("count",0);
            mProgressBar.setProgress(count);
        }
    }
}

廣播接收器通過接收到的由服務發送的廣播後將設置進度條。

使用IntentService

由於Service不是一個單獨的進程 ,也不是一個線程,它和應用程序在同一個進程中,所以我們應該避免在Service裏面進行耗時的操作。所以如果有耗時操作在Service裏,就必須開啓一個單獨的線程來處理!
其他使用跟Service相同,只是服務這一塊略有不同。
這裏寫一個IntentService類來具體說明一下

package com.example.administrator.myserviceapplication;

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

/**
 * Created by Administrator on 2015/9/9.
 */
public class MyIntentService extends IntentService {
    private int count=0;
    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public MyIntentService(String name) {
        super(name);
    }
    public MyIntentService(){
        this("");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("00000000000000000000000", "啓動了MyIntentService");
        while (true){
            count++;
            if (count>100){
                count=0;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Intent intent1=new Intent();
            intent1.setAction("com.downlowd.test");
            intent1.putExtra("count",count);
            sendBroadcast(intent1);
        }
    }
}

同樣不要忘了在Manifest裏進行註冊。在這裏可以看到,Service中的那段代碼是寫在一個線程中,而IntentService本身就是一個線程所以不需要寫在Thread中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章