我正在尝试创建一个单例类来报告连接状态。我的想法是,我可以在我的应用程序中的任何地方重复使用这个“服务”,例如:
getApplication().getConnectivityStatus().isConnected()
单例具有对ApplicationContext的引用。
我想在幕后使用BroadcastReceiver来检测连接变化。我正在连接“服务”中动态注册和取消注册,以实现更高级别的连接侦听器,例如:
getApplication().getConnectivityStatus().onConnectivity(mConnectivityCallback)
我只希望我自行决定注册BroadcastReceiver。但是,当应用程序被杀时,我在这里看到了一个洞。由于Application没有生命周期回调,如果应用程序被杀死,我无法挂钩取消注册BroadcastReceiver。
所以,1:我的应用程序死了,但是BroadcastReceiver(及其对ApplicationContext的引用)仍然被注册,并且它的onReceive方法被调用...会发生坏事吗?
2:有没有办法干净地做我想做的事情,或者我的模式是不是被误解了?
答案 0 :(得分:1)
我只想在BroadcastReceiver
中创建AndroidManifest.xml
registered。
从该接收器,您可以更新单身人士的连接状态,并且您不必担心取消注册。如果您不希望其他类能够更改状态,请将接收器和单例类放在单独的包中,并仅对该包进行setter方法可见性。
<强>更新强>
你的想法听起来非常有趣,拥有密封的服务&#34;处理网络更改并通知已注册的侦听器。但是,最后你的听众是Activites,这意味着一次总会有一个听众。此外,您不能在长期存在的对象中保留对Activity的强引用,并且必须使用Activite的生命周期回调。
我得出的结论是,你可以更好地使用经理类的非常简单的模式(我曾经实现过)。
Manager类看起来像这样:
public class NetworkManager {
private boolean connected;
private NetworkCallback callback;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateStatus(context);
}
};
private void updateStatus(Context context) {
ConnectivityManager conn = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();
//TODO do the rest here, e.g. set connected flag
connected = networkInfo.isConnected();
if (callback != null) {
callback.onConnectionChanged(connected);
}
}
public void registerContext(Context context, NetworkCallback callback) {
this.callback = callback;
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(receiver, filter);
updateStatus(context);
}
public void unregisterContext(Context context) {
callback = null;
context.unregisterReceiver(receiver);
}
public interface NetworkCallback {
void onConnectionChanged(boolean connected);
}
}
如果它仅被“活动”使用,则不必是单身人士。
使用它的活动:
public class NetworkActivity extends Activity implements NetworkManager.NetworkCallback {
private NetworkManager networkManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
networkManager = new NetworkManager();
}
@Override
protected void onResume() {
super.onResume();
networkManager.registerContext(this, this);
}
@Override
protected void onPause() {
networkManager.unregisterContext(this);
super.onPause();
}
@Override
public void onConnectionChanged(boolean connected) {
//TODO do something here
}
}
<强>提示强>
不要强迫自己使用不需要的复杂模式创建代码。仅在您的应用程序实际受益于其优势时才使用模式。
答案 1 :(得分:-1)
这里发布了通过服务测试互联网连接的示例代码,让用户知道是否通过服务存在网络可能会对您有所帮助
BroadcastReceiverClass.java
package com.sample;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
public class BroadcastReceiverClass extends android.content.BroadcastReceiver {
Context _con;
public BroadcastReceiverClass(Context _con) {
this._con = _con;
}
@Override
public void onReceive(Context context, Intent intent) {
intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
NetworkInfo currentNetworkInfo = (NetworkInfo) intent
.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
if (currentNetworkInfo.isConnected()) {
Toast.makeText(_con, "Connected", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(_con, "Not Connected", Toast.LENGTH_LONG).show();
}
}
}
/////////////////////////////////////////////// //////////////////////////
BroadCastSampleActivity .java
package com.sample;
import android.app.Activity;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
public class BroadCastSampleActivity extends Activity {
BroadcastReceiverClass mConnReceiver;
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mConnReceiver = new BroadcastReceiverClass(this);
this.registerReceiver(mConnReceiver, new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION));
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// this.unregisterReceiver(mConnReceiver);
}
// private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
// public void onReceive(Context context, Intent intent) {
// intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
// false);
// intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
// intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
//
// NetworkInfo currentNetworkInfo = (NetworkInfo) intent
// .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
// intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
//
// if (currentNetworkInfo.isConnected()) {
// Toast.makeText(getApplicationContext(), "Connected",
// Toast.LENGTH_LONG).show();
// } else {
// Toast.makeText(getApplicationContext(), "Not Connected",
// Toast.LENGTH_LONG).show();
// }
// }
// };
}
///////////////////////////////////////////// 清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sample"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
<activity android:name=".BroadCastSampleActivity"
android:label="BroadCast">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>