手机安全卫士:定位导航模块开发小结
毕设项目中,我负责的模块基本写完了。回望这一周,发现没怎么抽时间来写随笔。那么现在开始来对做的工作做下小结。可能没有很好的逻辑顺序把,基本应该是想到哪里写哪里了。
1、学习示例代码时,需要完全理解代码内容后,才能进行引用。
教训来源:在编写service时遇到了一个奇怪的BUG。准备使用Application来记录应用程序的状态及相关数据,让Service通过后台监听相关广播,来改变相应的全局变量。比如Service通过获取网络状态的变化,来改变Application中的网络状况参数。然后让其他系统组件来获取这些参数。代码基本如下:
1 //网络状况广播监听器 2 public class ConnectivitiesReceiver extends BroadcastReceiver{ 3 @Override 4 public void onReceive(Context context, Intent intent) { 5 // TODO Auto-generated method stub 6 // 通知用户网络连接变化 7 NetworkInfo wifiInfo = connectivityManager 8 .getNetworkInfo(ConnectivityManager.TYPE_WIFI); 9 NetworkInfo gprsInfo = connectivityManager 10 .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 11 12 Log.d("Info", 13 "gprsInfo =" + gprsInfo.toString()); 14 Log.d("Info", 15 "wifiInfo =" + wifiInfo.toString()); 16 17 if(wifiInfo.isConnected()){ 18 onConnected(); 19 app.SetNetowrkState(wifiInfo, 2); 20 return; 21 } 22 else if(gprsInfo.isConnected()){ 23 onConnected(); 24 app.SetNetowrkState(gprsInfo, 1); 25 return; 26 } 27 else{ 28 app.SetNetowrkState(null, 0); 29 onDisconnected(); 30 return; 31 } 32 } 33 34 35 public void onDisconnected(){ 36 isNetworkAvailable = false; 37 isServerAvailable = false; 38 39 TencentMapLBSApi.getInstance().removeLocationUpdate(); 40 Toast.makeText(getApplicationContext(), "Disconnected!", Toast.LENGTH_LONG).show(); 41 } 42 43 public void onConnected(){ 44 45 Toast.makeText(getApplicationContext(), "OnConnected!", Toast.LENGTH_LONG).show(); 46 47 TencentMapLBSApi.getInstance().requestLocationUpdate(getApplicationContext(), mListener); 48 isServerAvailable = true; 49 isNetworkAvailable = true; 50 } 51 } 52 }
通过获取相应的网络变化状态改变事件,调用相应的事件处理方法。将isNetworkAvailable参数采取相应的改变。由于Service本身也需要使用这个参数所以将其独立出来,并将相应的网络信息数据NetworkInfo更新到Application的全局变量中。
然后在系统其他组件中获取这些个全局变量。如在LocationHelpActivity中获取网络状况:
结果发现Activity根本无法取到改变后的全局变量值,然后通过Logcat进行追踪发现这些相应的方法确实做过,值确实改变过。但为什么无法取到呢?继续跟踪,我在使用Application时用的是单例方法:
1 public class MobileSafeguardApp extends Application { 2 private static MobileSafeguardApp mInstance = null; 3 4 //... 5 6 @Override 7 public void onCreate() { 8 super.onCreate(); 9 10 Log.d("InApp", "onCreate()!"); 11 mInstance = this; 12 } 13 14 public static MobileSafeguardApp getInstance(){ 15 Log.d("InApp", "getInstance()!"); 16 return mInstance; 17 } 18 19 //... 20 21 }
那么我们在getInstance()方法中使用Application的ToString()方法,即输出类名+@+类的Hashcode,然后通过日志发现在Service和Application中输出的对象的Hashcode不同。也就是说两次生成的对象不同。然后排除java代码的错误后,毫无头绪的寻找错误。最后在Manifest.xml中找到了一个可疑的地方。
1 <service 2 android:process=":remote" 3 android:name="com.mobilesafeguard.business.SafeguardService"> 4 </service>
对,就是这个process的属性值":remote"带来的问题,下面来分析下这个问题把:
在FireOfStar的一篇博文中有详细的对Service标签的详细分析,链接:http://blog.csdn.net/think_soft/article/details/7584895 。
这篇博文中指出了
android:process
这个属性用于设定服务所运行的进程名称。通常,应用程序的所有组件都运行在给应用程序创建的进程中,进程名与应用程序的包名相同。<application>元素的process属性能够给应用程序的所有组件设置一个不同的默认名称。但是每个组件自己的process属性都能够覆盖这个默认值,这样允许把应用程序分离到不同的多个进程中。如果这个属性值用“:”开头,则在需要的时候系统会创建一个新的,应用程序私有的进程,并且该服务也会运行在这个进程中。如果这个属性值用小写字母开头,那该服务就会运行在以这个属性值命名的全局进程中,它提供了使其工作的权限。这样就允许不同的应用程序组件来共享这个进程,从而降低资源的使用。
也就是说我在加上":remote"属性后,两次获得Application对象肯定是不同的。Service获取的对象是新的、私有的进程中对象。由于对象不同,那么这里的全局变量也就无法正常工作了。
那么改成"remote"就行了么?先来试试把,结果发现Console报出了错误:Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED.
这又是为什么呢?网上给的参考都不大靠谱,为什么改变合理的属性值会出现这种问题呢?malformed意思是畸形。这个错误产生有下面3个问题:
那么很显然是第三个了,但是这也没有解释出现问题的原因。我在没法找到问题的情况下,就把这个属性值删掉了,然后竟然发现通过了,而且这次取到的Application对象相同了。回头仔细的思索了下,发现那篇博文中可能出现了点问题把,这个process属性要么不设定即其所述的"remote"方式,要么就设定":remote"。
综上,回到到标题所述:学习示例代码时,需要完全理解代码内容后,才能进行引用。我就是在看别人示例代码时,没去思考这些必要元素的意义,导致浪费了很多时间。
2、TODO//未完待续
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。