您好,登錄后才能下訂單哦!
今天小編給大家分享一下Android廣播機(jī)制原理與開發(fā)的方法是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
標(biāo)準(zhǔn)廣播:完全異步執(zhí)行,廣播發(fā)出后,所有廣播接收器幾乎都同一時(shí)刻收到這條廣播(無法被截?cái)啵?/p>
有序廣播:同步執(zhí)行,廣播發(fā)出后同一時(shí)刻只會(huì)有一個(gè)廣播接收器能收到這條廣播消息,前面的接收器可以截?cái)嗾趥鬟f的廣播
廣播接收器可在代碼中注冊(cè)和AndroidManifest.xml中注冊(cè),前者為動(dòng)態(tài)注冊(cè),后者被稱為靜態(tài)注冊(cè)。
示例代碼:
public class MainActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView((R.layout.activity_main)); intentFilter= new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_VHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy(){ super.onDestroy(); unregisterReceiver(networkChangeReceiver); } class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent){ ConnectivityManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo(); if(networkInfo != null && networkInfo.isAvailable()){ Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show(); } Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show(); } } }
<receiver android:name=".BootCompleteReceiver" android:enabled="true" android:exported="true"></receiver>
Export屬性表示是否允許這個(gè)廣播接收器接收本程序以外的廣播,enable表示是否使用這個(gè)廣播接收器。
<receiver android:name=".BootCompleteReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
添加了filter就可以過濾了
可以通過左鍵新建-》其它來新建靜態(tài)注冊(cè)廣播
廣播接收器中不允許開線程,當(dāng)onReceive方法運(yùn)行較長(zhǎng)時(shí)間而沒結(jié)束時(shí),程序就會(huì)報(bào)錯(cuò),所以其中不能添加過多的邏輯或任何耗時(shí)操作。
@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView((R.layout.activity_main)); Button button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST"); sendBroadcast(intent); } }); }
通過點(diǎn)擊按鈕發(fā)送廣播
public class myBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "receiverd in myBroadcastReceiver", Toast.LENGTH_SHORT).show(); } }
這里是自定義的接收器
<receiver android:name=".myBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver>
在xml中定義過濾的廣播類型
廣播是一種跨進(jìn)程的通信方式
protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView((R.layout.activity_main)); Button button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST"); sendOrderedBroadcast(intent, null); } }); }
只需要修改一行代碼 sendOrederedBroadcast即可發(fā)送有序廣播,同時(shí)在接收器的xml文件中可以設(shè)置優(yōu)先級(jí)
<receiver android:name=".myBroadcastReceiver" android:enabled="true" android:exported="true"> <!-- 在這里設(shè)置優(yōu)先級(jí)--> <intent-filter android:priority="100"> <action android:name="com.example.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver>
如果想要在接收到廣播之后就讓廣播停止繼續(xù)傳遞呢,修改onReceive的代碼即可
public void onReceive(Context context, Intent intent) { Toast.makeText(context, "receiverd in myBroadcastReceiver", Toast.LENGTH_SHORT).show(); // 停止繼續(xù)傳遞 abortBroadcast(); }
前面我們發(fā)送和接收的廣播全部屬于系統(tǒng)全局廣播,即發(fā)出的廣播可以被其他任何應(yīng)用程序接收到,并且我們也可以接收來自于其他任何應(yīng)用程序的廣播。這樣就很容易引起安全性的問題,比如說我們發(fā)送的一些攜帶關(guān)鍵性數(shù)據(jù)的廣播有可能被其他的應(yīng)用程序截獲,或者其他的程序不停地向我們的廣播接收器里發(fā)送各種垃圾廣播。
使用本地廣播則發(fā)出的廣播只能在應(yīng)用程序內(nèi)部傳遞,并且接收器也只能接收來自本應(yīng)用程序發(fā)出的廣播。
public class MainActivity extends AppCompatActivity { private IntentFilter intentFilter; private LocalReceiver localReceiver; private LocalBroadcastManager localBroadcastManger; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView((R.layout.activity_main)); localBroadcastManger = LocalBroadcastManager.getInstance(this); //獲取實(shí)例 Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST"); localBroadcastManger.sendBroadcast(intent); //發(fā)送本地廣播 } }); intentFilter = new IntentFilter(); intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST"); localReceiver = new LocalReceiver(); localBroadcastManger.registerReceiver(localReceiver, intentFilter); //注冊(cè)本地廣播監(jiān)聽器 } @Override protected void onDestroy(){ super.onDestroy(); localBroadcastManger.unregisterReceiver(localReceiver); } class LocalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent){ Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show(); } } }
代碼的不同主要在于需要首先獲取實(shí)例,然后還要有注冊(cè)。
需要注意的是,本地廣播無法通過靜態(tài)注冊(cè)來接收。
強(qiáng)制下線功能首先需要實(shí)現(xiàn)下關(guān)閉所有的活動(dòng)的功能,新建一個(gè)ActivityCollector類管理所有的活動(dòng)
public class ActivityCollector { public static List<Activity> activities = new ArrayList<>(); public static void addActivity(Activity activity){ activities.add(activity); } public static void removeActivity(Activity activity){ activities.remove(activity); } public static void finishAll(){ for(Activity activity:activities){ if(!activity.isFinishing()){ activity.finish(); } } } }
然后創(chuàng)建baseActivity類作為活動(dòng)的父類,代碼如下:
public class BaseActivity extends AppCompatActivity { private ForceOfflineReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); ActivityCollector.addActivity(this); } @Override protected void onResume(){ super.onResume(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE"); receiver = new ForceOfflineReceiver(); registerReceiver(receiver, intentFilter); } @Override protected void onPause(){ super.onPause(); if(receiver != null){ unregisterReceiver(receiver); receiver = null; } } @Override protected void onDestroy(){ super.onDestroy(); ActivityCollector.removeActivity(this); } class ForceOfflineReceiver extends BroadcastReceiver{ @Override public void onReceive(final Context context, Intent intent){ AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("warning"); builder.setMessage("You are forced to be offline"); builder.setCancelable(false); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int which) { ActivityCollector.finishAll(); //銷毀所有活動(dòng) Intent intent = new Intent(context, LoginActivity.class); context.startActivity(intent); //重新啟動(dòng)loginActivity } }); builder.show(); } } }
我們可以注意到,之前編寫注冊(cè)和銷毀接收器的時(shí)候是在onCreate和onDestroy這兩個(gè)函數(shù)里的,但是上面代碼中卻寫在了onResume和onPause里面,這是因?yàn)槲覀兠看味贾恍枰跅m數(shù)幕顒?dòng)接收廣播,非棧頂活動(dòng)沒必要接收這條廣播。
除此之外,我們創(chuàng)建一個(gè)登陸的活動(dòng),在活動(dòng)頁(yè)面上放置輸入框,并編寫登錄邏輯
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ui.login.LoginActivity"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="60dp" tools:ignore="MissingConstraints"> <TextView android:layout_width="90dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textSize="18sp" android:text="Account:"/> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:id="@+id/account" android:layout_weight="1" android:layout_gravity="center_horizontal"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="60dp" tools:ignore="MissingConstraints"> <TextView android:layout_width="90dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textSize="18sp" android:text="password:"/> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:id="@+id/password" android:layout_weight="1" android:layout_gravity="center_horizontal"/> </LinearLayout> <Button android:layout_width="match_parent" android:layout_height="60dp" android:id="@+id/login" android:text="Login" tools:ignore="MissingConstraints"></Button> </androidx.constraintlayout.widget.ConstraintLayout>
public class LoginActivity extends AppCompatActivity { private EditText accountEdit; private EditText passwordEdit; private Button login; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); accountEdit = (EditText) findViewById(R.id.account); passwordEdit = (EditText) findViewById(R.id.password); login = (Button) findViewById(R.id.login); login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String account = accountEdit.getText().toString(); String password = passwordEdit.getText().toString(); //如果賬號(hào)是admin 且密碼是123456則登錄成功 if(account.equals("admin") && password.equals("123456")){ Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); finish(); }else { Toast.makeText(LoginActivity.this, "account is invalid", Toast.LENGTH_SHORT).show(); } } }); } }
這樣就模擬了登錄的窗口,然后在mainActivity中加入觸發(fā)強(qiáng)制下線的代碼
public class MainActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button forceOffline = (Button) findViewById(R.id.force_offline); forceOffline.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.example.broadcastbestpractice.FROCE_OFFLINE"); sendBroadcast(intent); } }); } }
這樣邏輯就差不多了,下面去AndroidManifest.xml中修改下程序入口即可。
以上就是“Android廣播機(jī)制原理與開發(fā)的方法是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。