当前位置: 首页 > 科技观察

10分钟让你实现APP网络状态变化全局提醒

时间:2023-03-12 02:10:38 科技观察

万万没想到用户会按照你预设的步骤来操作APP新项目刚开始推广,营销人员跟我抱怨说会有用户在使用的时候总是会出现各种各样的问题出现各种各样的问题,大部分都是因为用户操作不当造成的,但是在用户眼里的结论就是“你的APP不好用”。举个例子,有的用户在使用APP时禁止APP接入移动网络,有的用户干脆不打开移动数据开关或WIFI开关。但是作为开发者,我们应该避免用户思考。当用户遇到问题时,APP应该能够引导用户进行设置,所以才有了这篇文章。我们希望当用户的网络连接不可用时,及时提醒用户当前的网络状态。当连接恢复时,隐藏提示视图,我们希望这个提示视图在所有需要网络的页面上都起作用。思路是这样的:使用BaseActivity,所有页面都继承这个文件,在这个文件中实现根据网络状态显示和隐藏提示。好吧,事不宜迟,给你看代码。1.实现一个监听网络状态变化的广播接收器。我们使用广播接收器来接收网络变化的意图。这里我们直接使用静态注册的方式,因为不需要在每个页面单独注册这个Receiver,太重量级了。NetworkConnectChangedReceiver.javapublicclassNetworkConnectChangedReceiverextendsBroadcastReceiver{privatestaticfinalStringTAG="NetworkConnectChanged";@OverridepublicvoidonReceive(Contextcontext,Intentintent){//**判断当前网络连接状态是否可用*/booleanisConnected=NetUtils.isConnected(context);Log.dce(TAG,"onReceiver当前网络"+isConnected);EventBus.getDefault().post(newNetworkChangeEvent(isConnected));}}Event事件:publicclassNetworkChangeEvent{publicbooleanisConnected;//是否有网络publicNetworkChangeEvent(booleanisConnected){this.isConnected=isConnected;}}判断网络是否连接可用:/***判断网络是否连接*@paramcontext*@return*/publicstaticbooleanisConnected(Contextcontext){ConnectivityManagerconnectivity=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);if(null!=connectivity){NetworkInfoinfo=connectivity.getActiveNetworkInfo();if(null!=info&&info.isConnected()){if(info.getState()==NetworkInfo.State.CONNECTED){returntrue;}}}returnfalse;}静态注册接收器:2.监听BaseActivity中的事件并处理提示view看到EventBus的时候是不是已经知道我的实现了?(笑XD),没错,说了很久的EventBus当然可以使用观察者模式来实现,这样就不需要依赖第三方库了,但是我们需要的是快速实现,以及对原代码进行尽可能少的改动,引入观察者模式显然不如直接走EventBus方便。BaseActivity.javapublicclassBaseActivityextendsActivity{protectedContextmContext;protectedACachemACache;protectedbooleanmCheckNetWork=true;//默认检测网络状态ViewmTipView;WindowManagermWindowManager;WindowManager.LayoutParamsmLayoutParams;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstance=ACchemtext=thisState);(mContext);MyApp.addActivity(this);initTipView();//初始化提示ViewEventBus.getDefault().register(this);}@OverrideprotectedvoidonResume(){super.onResume();MobclickAgent.onResume(this);//无网打开APP时,系统不会发送网络状态变化的Intent,需要手动勾选hasNetWork(NetUtils.isConnected(mContext));}@OverrideprotectedvoidonPause(){super.onPause();MobclickAgent.onPause(this);}@OverrideprotectedvoidonDestroy(){super.onDestroy();MyApp.removeActivity(this);EventBus.getDefault().unregister(this);}@Overridepublicvoidfinish(){super.finish();//当提示查看Cl动态添加后直接os页面会导致View内存溢出,所以需要去掉if(mTipView!=null&&mTipView.getParent()!=null){mWindowManager.removeView(mTipView);}}@Subscribe(threadMode=ThreadMode.MAIN)publicvoidonNetworkChangeEvent(NetworkChangeEventevent){hasNetWork(event.isConnected);}privatevoidhasNetWork(booleanhas){if(isCheckNetWork()){if(has){if(mTipView!=null&&mTipView.getParent()!=null){mWindowManager.removeView(mTipView);}}else{if(mTipView.getParent()==null){mWindowManager.addView(mTipView,mLayoutParams);}}}}publicvoidsetCheckNetWork(booleancheckNetWork){mCheckNetWork=checkNetWork;}publicbooleanisCheckNetWork(){returnmCheckNetWork;}privatevoidinitTipView(){LayoutInflaterinflater=getLayoutInflater();mTipView=inflater.inflate(R.layout.layout_network_tip,null);//提示View布局mWindowManager=(WindowManager)this.getSystemService(Context.WINDOW_SERVICE);mLayoutParams=newWindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.TYPE_APPLICATION,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,PixelFormat.TRANSLUCENT);//当使用非CENTER时,可以通过设置XY的值改变View的位置mLayoutParams.gravity=Gravity.TOP;mLayoutParams.x=0;mLayoutParams.y=0;}}默认情况下,所有继承BaseActivity的页面都会在网络状态改变或没有网络时显示提示。如果页面不需要网络状态提示,可以在页面的onCreate方法中调用setCheckNetWork(false)。由于我所有的页面都有一个50dp高度的工具栏,所以我直接在R.layout.layout_network_tip文件中设置上边距。也可以设置mLayoutParams.x=0;mLayoutParams.y=0;在BaseActivity中动态设置每个页面提示的位置。最终效果如下图所示:所有的ToDo页面都应该能够在网络连接恢复后自动重新发起网络请求。实现原理其实很简单。在BaseActivity中添加一个reConnect()方法,在网络恢复和移除提示View时调用。只需在每个页面中覆盖此方法即可。