手机安全卫士:定位导航模块开发小结

  毕设项目中,我负责的模块基本写完了。回望这一周,发现没怎么抽时间来写随笔。那么现在开始来对做的工作做下小结。可能没有很好的逻辑顺序把,基本应该是想到哪里写哪里了。

 

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中获取全局Application对象
使用Application中的全局变量

  结果发现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 }
Application定义代码

 

  那么我们在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>
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个问题:

  Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED  
    1、没有manifest.zml文件
  2、xml中的包与应用的包不相同
  3、android:process值不对

  那么很显然是第三个了,但是这也没有解释出现问题的原因。我在没法找到问题的情况下,就把这个属性值删掉了,然后竟然发现通过了,而且这次取到的Application对象相同了。回头仔细的思索了下,发现那篇博文中可能出现了点问题把,这个process属性要么不设定即其所述的"remote"方式,要么就设定":remote"。

  综上,回到到标题所述:学习示例代码时,需要完全理解代码内容后,才能进行引用。我就是在看别人示例代码时,没去思考这些必要元素的意义,导致浪费了很多时间。

2、TODO//未完待续

手机安全卫士:定位导航模块开发小结,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。