Android Widget开发总结

 前段时间在做一个Weather Widget,没有自己的Service接口,只有调用google api来实现。google的api还是挺好用的。可以使用google提供的接口获取城市列表和天气信息,天气可以通过好种方式查询,如城市名称,经纬度,邮编。google api 还提供了中文显示。所以用起来很方便。我看过一些weather widget的应用,都做得挺好的,比如过Go Weather 他们用的是经过自己解析的天气;再比如说FancyWidgetPro,是通过 http://weather.weatherbug.com 来获取天气情况的。好了,闲话少说,下面来总结下我在Widget开发中遇到的问题和应该注意的问题。

    1、Widget中通过按钮点击进入Activity,这个比较简单。主要是通过RemoteViews的setOnClickPendingIntent时间来实现。请看下面代码:

view plain copy to clipboard print ?
  1. Intent intent = new Intent(context,WeatherActivity.class);  
  2.         intent.setAction(Globals.ACTION_APP_WIDGET_WEATHERACTIVITY);  
  3.         PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  4.         views.setOnClickPendingIntent(R.id.weathericon, pIntent);  
Intent intent = new Intent(context,WeatherActivity.class); intent.setAction(Globals.ACTION_APP_WIDGET_WEATHERACTIVITY); PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.weathericon, pIntent);

 

    2、通过Service刷新界面,由于之前没有做过Widget方面的项目,所以在开始使用广播的形式,启动线程。来更新界面,是在是不爽。于是网上查了下,都是用Service来刷新界面的。那么具体如何使用呢?在AppWidgetProvider中设置Intent,并指定其Action,使用RemoteViews的setOnClickPendingIntent方法与具体的控件(weatherDate1)关联;启动Service服务;在继承Service的类中的onStart方法中得到设置的Action,做相应的动作。请看下面代码段:

    在继承AppWidgetProvider的类中:

   

view plain copy to clipboard print ?
  1. Intent update1 = new Intent(Globals.ACTION_APP_WIDGET_UPDATE_1);  
  2.         PendingIntent pendingUpdate1 = PendingIntent.getService(context, 0, update1, 0);  
  3.         views.setOnClickPendingIntent(R.id.weatherDate1, pendingUpdate1);  
Intent update1 = new Intent(Globals.ACTION_APP_WIDGET_UPDATE_1); PendingIntent pendingUpdate1 = PendingIntent.getService(context, 0, update1, 0); views.setOnClickPendingIntent(R.id.weatherDate1, pendingUpdate1);

    启动服务:

   

view plain copy to clipboard print ?
  1. context.startService(new Intent(Globals.ACTION_APP_WIDGET_SERVICE));    
context.startService(new Intent(Globals.ACTION_APP_WIDGET_SERVICE));

    在继承Service的类中:

   

view plain copy to clipboard print ?
  1. if(Globals.ACTION_APP_WIDGET_UPDATE_2.equals(action)){  
  2.             Log.i(TAG, "update_2");  
  3.             updateWeatherInfo(views,1);  
  4.         }  
if(Globals.ACTION_APP_WIDGET_UPDATE_2.equals(action)){ Log.i(TAG, "update_2"); updateWeatherInfo(views,1); }

   

    以上只是简单的点击刷新操作,那么如果天气要15分钟获取更长的时间刷新界面,那么怎么办呢?必须用到线程,用线程来控制。如果让线程sleep15分钟或者更长时间,会出现ANR的问题。很是麻烦。请看第三点。

    3、线程的使用

    Ok,怎么避免ANR,网上有详细的说明,请google!不再多说,我也说不明白,哈哈。线程的使用请看下面代码:

   

view plain copy to clipboard print ?
  1. private Runnable runnable = new Runnable() {  
  2.           
  3.         @Override  
  4.         public void run() {  
  5.             while (isRunRefresh && refreshTime!=0) {  
  6.                 Log.i(TAG, "==real time refersh!==");  
  7.                 try {  
  8.                     Thread.sleep(refreshTime); // 这里做一些耗时的操作   
  9.                     mHandler.sendEmptyMessage(1000); // 发送消息给UI   
  10.                 } catch (InterruptedException e) {  
  11.                     e.printStackTrace();  
  12.                 }  
  13.             }  
  14.         }  
  15.     };  
  16.       
  17.     private Handler mHandler = new Handler(){  
  18.         public void handleMessage(android.os.Message msg) {  
  19.             if (msg.what==1000) {  
  20.                 updateWeatherInfo(views,-1); // 更新消息   
  21.             }  
  22.         };  
  23.     };  
private Runnable runnable = new Runnable() { @Override public void run() { while (isRunRefresh && refreshTime!=0) { Log.i(TAG, "==real time refersh!=="); try { Thread.sleep(refreshTime); // 这里做一些耗时的操作 mHandler.sendEmptyMessage(1000); // 发送消息给UI } catch (InterruptedException e) { e.printStackTrace(); } } } }; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { if (msg.what==1000) { updateWeatherInfo(views,-1); // 更新消息 } }; };

    启动线程:

   

view plain copy to clipboard print ?
  1. mThread = new Thread(runnable); // 主线程中创建子线程   
  2.         mThread.start();  
mThread = new Thread(runnable); // 主线程中创建子线程 mThread.start();

    4、获取xml文件后中文的显示问题

   

view plain copy to clipboard print ?
  1. builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();  
  2.                 InputSource inputSource = new InputSource();  
  3.                 inputSource.setByteStream(stream);  
  4.                 inputSource.setEncoding("gbk");  // 设置InputSource的编码格式GBK  
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); InputSource inputSource = new InputSource(); inputSource.setByteStream(stream); inputSource.setEncoding("gbk"); // 设置InputSource的编码格式GBK

 

特此申明:这不是教程,这只是个人总结!欢迎交流。O(∩_∩)O哈哈~

你可能感兴趣的:(Android Widget开发总结)