Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> ANDROID-當網絡發生變化時使用BroadcastReceiver和service通知

ANDROID-當網絡發生變化時使用BroadcastReceiver和service通知

編輯:關於Android編程

Android 中的 Service

按運行地點分類:
1、本地服務(Local) 該服務依附在主進程上, 服務依附在主進程上而不是獨立的進程,這樣在一定程度上節約了資源,另外Local服務因為是在同一進程因此不需要IPC,也不需要AIDL。相應bindService會方便很多。 主進程被Kill後,服務便會終止。 非常常見的應用如:HTC的音樂播放服務,天天動聽音樂播放服務。
2、遠程服務(Remote) 該服務是獨立的進程, 服務為獨立的進程,對應進程名格式為所在包名加上你指定的android:process字符串。由於是獨立的進程,因此在Activity所在進程被Kill的時候,該服務依然在運行,不受其他進程影響,有利於為多個進程提供服務具有較高的靈活性。 該服務是獨立的進程,會占用一定資源,並且使用AIDL進行IPC稍微麻煩一點。 一些提供系統服務的Service,這種Service是常駐的。

按運行類型分類:

前台服務 會在通知一欄顯示 ONGOING 的 Notification, 當服務被終止的時候,通知一欄的 Notification 也會消失,這樣對於用戶有一定的通知作用。常見的如音樂播放服務。
後台服務 默認的服務即為後台服務,即不會在通知一欄顯示 ONGOING 的 Notification。 當服務被終止的時候,用戶是看不到效果的。某些不需要運行或終止提示的服務,如天氣更新,日期同步,郵件同步等。

3、Service的生命周期
onCreate  onStart  onDestroy  onBind

1). 被啟動的服務的生命周期:如果一個Service被某個Activity 調用 Context.startService 方法啟動,那麼不管是否有Activity使用bindService綁定或unbindService解除綁定到該Service,該Service都在後台運行。如果一個Service被startService 方法多次啟動,那麼onCreate方法只會調用一次,onStart將會被調用多次(對應調用startService的次數),並且系統只會創建Service的一個實例(因此你應該知道只需要一次stopService調用)。該Service將會一直在後台運行,而不管對應程序的Activity是否在運行,直到被調用stopService,或自身的stopSelf方法。當然如果系統資源不足,android系統也可能結束服務。

2). 被綁定的服務的生命周期:如果一個Service被某個Activity 調用 Context.bindService 方法綁定啟動,不管調用 bindService 調用幾次,onCreate方法都只會調用一次,同時onStart方法始終不會被調用。當連接建立之後,Service將會一直運行,除非調用Context.unbindService 斷開連接或者之前調用bindService 的 Context 不存在了(如Activity被finish的時候),系統將會自動停止Service,對應onDestroy將被調用。

3). 被啟動又被綁定的服務的生命周期:如果一個Service又被啟動又被綁定,則該Service將會一直在後台運行。並且不管如何調用,onCreate始終只會調用一次,對應startService調用多少次,Service的onStart便會調用多少次。調用unbindService將不會停止Service,而必須調用 stopService 或 Service的 stopSelf 來停止服務。

4). 當服務被停止時清除服務:當一個Service被終止(1、調用stopService;2、調用stopSelf;3、不再有綁定的連接(沒有被啟動))時,onDestroy方法將會被調用,在這裡你應當做一些清除工作,如停止在Service中創建並運行的線程。

特別注意:

1、你應當知道在調用 bindService 綁定到Service的時候,你就應當保證在某處調用 unbindService 解除綁定(盡管 Activity 被 finish 的時候綁定會自      動解除,並且Service會自動停止);

2、你應當注意 使用 startService 啟動服務之後,一定要使用 stopService停止服務,不管你是否使用bindService;

3、同時使用 startService 與 bindService 要注意到,Service 的終止,需要unbindService與stopService同時調用,才能終止 Service,不管 startService 與 bindService 的調用順序,如果先調用 unbindService 此時服務不會自動終止,再調用 stopService 之後服務才會停止,如果先調用 stopService 此時服務也不會終止,而再調用 unbindService 或者 之前調用 bindService 的 Context 不存在了(如Activity 被 finish 的時候)之後服務才會自動停止;

4、當在旋轉手機屏幕的時候,當手機屏幕在“橫”“豎”變換時,此時如果你的 Activity 如果會自動旋轉的話,旋轉其實是 Activity 的重新創建,因此旋轉之前的使用 bindService 建立的連接便會斷開(Context 不存在了),對應服務的生命周期與上述相同。

5、在 sdk 2.0 及其以後的版本中,對應的 onStart 已經被否決變為了 onStartCommand,不過之前的 onStart 任然有效。這意味著,如果你開發的應用程序用的 sdk 為 2.0 及其以後的版本,那麼你應當使用 onStartCommand 而不是 onStart。

Android—廣播

廣播: 實現了不同的程序之間的數據傳輸與共享,因為只要是和發送廣播的action相同的接受者都能接受這個廣播。典型的應用就是android自帶的短信,電話等等廣播,只要我們實現了他們的action的廣播,那麼我們就能接收他們的數據了,以便做出一些處理。比如說攔截系統短信,攔截騷擾電話等等 2.起到了一個通知的作用,比如在service中要通知主程序,更新主程序的UI等。因為service是沒有界面的,所以不能直接獲得主程序中的控件,這樣我們就只能在主程序中實現一個廣播接受者專門用來接受service發過來的數據和通知了。

廣播的實現方式有2種:

android提供了兩種注冊廣播接受者的形式,分別是在程序中動態注冊和在xml中指定。他們之間的區別就是作用的范圍不同,程序動態注冊的接收者只在程序運行過程中有效,而在xml注冊的接收者不管你的程序有沒有啟動有會起作用。

下面就以一個例子來說明service和廣播的使用。(以一個簡單的例子來說明: 當手機得wifi開啟和關閉說通知activity並在activity的頭部顯示網絡有問題。)

首先新建個service

package servicetest.zkk.com.myapplication;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;
import android.text.TextUtils;


/**
 * 網絡發生變化時的service
 */
public class MyNetworkStateService extends Service {

    private ConnectivityManager connectivityManager;
    private NetworkInfo info;
    public static final String ACTION_NO_CONNECTION = "ACTION_NO_CONNECTION"; //網絡沒有連接
    public static final String ACTION_CONNECTIONED = "ACTION_CONNECTIONED";   //網絡連接

    private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
              //當網絡發生變化時
            String action = intent.getAction();
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
                info = connectivityManager.getActiveNetworkInfo();
                if(info != null && info.isAvailable()) {
                    String name = info.getTypeName();
                    if(TextUtils.equals("WIFI", name)) {
                    } else {
                    }
                    sendNetworkStateBroadCast(ACTION_CONNECTIONED);
                } else {
                    sendNetworkStateBroadCast(ACTION_NO_CONNECTION);
                }
            }
        }
    };

    /**
     * 發送本地廣播通知網絡狀態
     * @param action
     */
    private void sendNetworkStateBroadCast(String action) {
        if (TextUtils.equals(ACTION_CONNECTIONED, action) ||
                TextUtils.equals(ACTION_NO_CONNECTION, action)) {
            Intent intent = new Intent(action);
            LocalBroadcastUtils.send(getApplication(), intent);
        }
    }


    public MyNetworkStateService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(broadcastReceiver,intentFilter);
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(broadcastReceiver);
        super.onDestroy();
    }
}

再 AndroidManifest.xml中注冊這個service

注意在service中得代碼

 @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter intentFilter=new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(broadcastReceiver,intentFilter);
    }

意思就是說在service啟動的時候注冊了一個廣播,ConnectivityManager.CONNECTIVITY_ACTION這個就是系統在網絡發生變化時候得action,比如wifi關閉、wifi重新連接等。

利用LocalBroadcastManager管理廣播

package servicetest.zkk.com.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;

/**
 * 利用LocalBroadcastManager管理廣播
 */
public class LocalBroadcastUtils {
    /**
     * 注冊廣播
     *
     * @param context
     * @param broadcastReceiver
     * @param intentFilter
     */
    public static void register(Context context, BroadcastReceiver broadcastReceiver, IntentFilter intentFilter) {
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
        localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter);
    }

    /**
     * 注銷廣播
     *
     * @param context
     * @param broadcastReceiver
     */
    public static void unregister(Context context, BroadcastReceiver broadcastReceiver) {
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
        localBroadcastManager.unregisterReceiver(broadcastReceiver);
    }

    /**
     * 發送廣播
     *
     * @param context
     * @param intent
     */
    public static void send(Context context, Intent intent) {
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
        localBroadcastManager.sendBroadcast(intent);
    }
}

``

這是一個管理類,對廣播進行管理。

下面就來看看在activity中如何操作`

private void registerBroadcast() {
    mNetworkBroadcastReceiverHelper = new NetworkBroadcastReceiverHelper(ctx,
            new NetworkBroadcastReceiverHelper.OnNetworkStateChangedListener(){
                @Override
                public void onConnected() {
                    //連接時的事件
                }
                @Override
                public void onDisConnected() {
                    //沒有連接時的事件
                }
            });
    mNetworkBroadcastReceiverHelper.register();
}

/**
 * 注銷廣播
 */
private void unregisterBroadcast() {
    mNetworkBroadcastReceiverHelper.unregister();
}


這其實就是一個網絡狀態廣播接受者幫助類,在其中定義了接口,這樣在activity中就有了回調。繼續在actiivty中操作。


@Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       ctx=this;
       setContentView(R.layout.activity_main);
       mViewNoNetwork=(View)findViewById(R.id.include_home_fragment_network);
       registerBroadcast();
       Intent intents=new Intent(this, MyNetworkStateService.class);
       startService(intents);
   }

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Intent intents=new Intent(this, MyNetworkStateService.class);
    stopService(intents);
}

/**
     *注冊廣播
     */
    private void registerBroadcast() {
        mNetworkBroadcastReceiverHelper = new NetworkBroadcastReceiverHelper(ctx,
                new NetworkBroadcastReceiverHelper.OnNetworkStateChangedListener(){
                    @Override
                    public void onConnected() {
                        //連接時的事件
                        mViewNoNetwork.setVisibility(View.GONE);
                    }
                    @Override
                    public void onDisConnected() {
                        //沒有連接時的事件
                        mViewNoNetwork.setVisibility(View.VISIBLE);
                    }
                });
        mNetworkBroadcastReceiverHelper.register();
    }

“`
在onConnected和onDisConnected方法中就可以進行處理了,分別為網絡連接成功、連接失敗。

效果圖如下:
這裡寫圖片描述

代碼下載地址:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPmNzZG4tYXOw5rG+OiA8YSBocmVmPQ=="http://download.csdn.net/detail/zhang58246500/9535186">http://download.csdn.net/detail/zhang58246500/9535186
csdn-eclipse版本: http://download.csdn.net/detail/zhang58246500/9535164
github地址: https://github.com/panacena/Myservice

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved