8月 042015
 

  默认情况下,当Android应用横竖屏切换时,Activity会销毁后并重新创建,依次执行OnPause->OnSaveInstance->OnStop->OnDestroy->OnCreate->OnStart->OnResume。 网上流传的防止Activity横竖屏切换重新创建的方法是设置android:configChanges=”keyboardHidden|orientation”,但是笔者测试发现,对于运行于Android api版本10之后的版本不再需要keyboardHidden,但是为了兼容肯定还是要加上此项;而对于项目的targetVersion大于等于13的,必须在此参数中再加上一个screenSize才可以,因为13版本以上切换横竖屏时也会触发屏幕尺寸的变化。

  因此,笔者对各种情况的生命周期总结如下:

  1)对于不设置configChanges或者设置configChanges=”orientation”的,横竖屏切换时重新创建Activity,依次执行OnPause->OnSaveInstance->OnStop->OnDestroy->OnCreate->OnStart->OnResume

  2)设置android:configChanges=”orientation|keyboardHidden|screenSize”后,横竖屏切换时不会重新创建Activity,只会执行Activity的onConfigurationChanged事件

  官方参考文档:http://developer.android.com/guide/topics/manifest/activity-element.html#config

 

7月 262015
 

  今天被一个简单的selector对象给坑了,设置了state_pressed的drawable,但是死活都没有反应,后来在网上搜索,原来几个状态的顺序是很重要的!

  android在匹配状态的时候,从上到下开始匹配,如果匹配到合适的状态就终止了,所以正常状态一定要放到最下面,否则其他的状态可能不会被显示。

  如下代码:

  正常的状态一定要放在最下面,其他的状态根据情况排序。

7月 242015
 

  在Android4.0之前,服务是可以在开机时自动运行的,但是在Android4.0以后,为了安全起见,防止一些非法的后台服务在开机后自动运行,用户必须打开一个Activity后才可以启动服务。

  那么我们想想,如果我们不是做一些非法的操作是否可以有其他的变通方法解决这个问题呢。

  如果是要更新桌面小组件的数据,那么我们可以在小组件服务创建时启动数据更新服务,如下:

 *
Android4.0之前设置服务开机自启动的方法

  首先AndroidManifest.xml中加入

  创建用于接收RECEIVE_BOOT_COMPLETED广播的BroadcastReceiver类

  在AndroidManifest.xml中声明这个receiver类

  BOOT_COMPLETED:当系统启动完成时发送这个广播
  QUICKBOOT_POWERON:HTC的一些手机有快速启动,这个action是针对快速启动情况的
  ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:这个action是针对程序安装到sd卡的时候,sd卡上的应用加载完成时发送此广播

7月 232015
 

话不多说,先上代码:

首先在AndroidManifest.xml中申请WakeLock权限

然后在你需要保持系统一直运行的地方写下面的代码:

原理:

PowerManager,手机的电源管理相关组件。 WakeLock,用于程序控制是否一直保持手机运行状态组件。WakeLock的保持运行共包括四个类型,最好使用比较低的级别,以降低手机电池的使用量。

Flag值 CPU 屏幕 键盘
PARTIAL_WAKE_LOCK On* Off Off
SCREEN_DIM_WAKE_LOCK On Dim Off
SCREEN_BRIGHT_WAKE_LOCK On Bright Off
FULL_WAKE_LOCK On Bright Bright

所有的类型CPU都是保持运行,屏幕和键盘分为关闭、暗光、亮光三个级别,我们经常用的应该是PARTIAL_WAKE_LOCK,保持CPU运行就行了。

在服务类中的使用

对于编写的android服务,在手机锁屏休眠后,服务也可能会停止运行,我们可以使用此方法让服务保持运行,但代码写法和上面稍有不同。如下:

http://svn1.bcoder.com

 

7月 222015
 

在Android中添加子菜单的方法很简单,只要在设计菜单的时候给菜单的item增加menu子节点就可以,菜单设计文件的xml代码如下:

在Activity中的响应代码和正常的菜单一样,如下:

这种下拉菜单的缺点就是子菜单的位置无法控制。

7月 112015
 

1. 在AndroidManifest.xml中加入以下权限

2. 注册网络变化监听事件,在AndroidManifest.xml中加入以下代码

android:name的值为NetworkChangeReceiver为类名

3,实现NetworkChangerReceiver类

 

7月 062015
 

  在Android Virtual Device Manager中打开一个Android模拟器,可以通过Ctrl+F11或者Ctrl+F12来切换模拟器的横竖屏,在Windows7+Eclipse环境下这两个快捷键功能一样,不知道为什么如此设置。如下图:

20160306151308

  按Ctrl+F11或者Ctrl+F12后变为横屏效果

20160306151332

  再按一次快捷键恢复到竖屏效果

 

 

 Posted by on 2015-07-06
5月 132015
 

  App Widget是Android中可以用于显示在桌面或者锁屏中的便捷显示组件,对于一些应用来说,比如天气预报、音乐播放器、股票行情等应用,开发相应的组件放到桌面上可以让用户更快捷高效的查看内容,提高用户的效率,增强用户的体验,让应用更加受用户欢迎。

一、插件原理介绍

  因为小插件要长期在桌面上,所以小插件不能通过应用的形式来长期运行,那样会消耗很多的系统资源,所在在安卓系统中,插件是作为插件宿主的一部分而存在,而不是一个应用程序,而插件宿主由安卓系统来控制,这时插件和应用之间的数据传输就不能像Activity之间一样单纯的用Intent来控制了。那么插件的数据是通过什么形式传输的呢?答案是使用的广播的方式来传输数据,插件本身是一个BroadcastReceiver,接收到消息或数据后再进行显示。由此可见,插件并没有Activity,只是一个BroadcastReceiver,而用于处理界面的对象则是RemoteViews而不是View对象。

  Android中的桌面插件虽然拥有和Activity基本一样的布局,但插件中的组件却不能直接通过组件对象直接操作,比如在Activity中我们要改变一个TextView显示的文字,我们只需要用findViewById找到这个对象并赋给一个定义好的TextView对象,然后用这个对象的setText方法修改显示文字即可。但是在插件中却不可以这样操作,因为他本身并不存在Activity,不提供findViewById这样的方法来寻找对象。具体如何操作以后会讲到,下面我们先来看看要创建一个组件所必须的几个对象。

二、三个必要组件

  通过上面的描述我们可以知道,一个小插件至少要有两个对象才可以存在,第一就是一个可用于接收消息的BroadcastReceiver对象,在安卓中又针对插件做了一次封装,那我们需要使用的就是继承自AppWidgetProvider类;另外一个,很显而易见的就是要有一个基本的布局,一个layout对象。那么还没完,我们还需要一个对象来描述这个Provider,这就是第三个基本组件AppWidgetProviderInfo对象,一个xml描述文件。下面我们就对这三个对象进行详细描述。

1、AppWidgetProvider类

  AppWidgetProvider继承自BroadcastReceiver对象,其实就是一个广播接收对象类,它自身又实现了几个用于处理插件被更新、变可用、变不可用、被删除时的方法。下面是一个示例文件:

1) onReceive: 此方法实际上是覆盖了父类BroadcastReceiver中的onReceive方法,用于接收广播消息并根据不同的消息内容执行不同的操作。在AppWidgetProvider中已经对更新、删除等消息内容做了处理,并新建了onUpdate、onDeleted等方法用于给开发者响应消息。需要注意的是:开发者可以自定义广播消息,并在onReceive中接收并做相应的操作。
2) onAppWidgetOptionsChanged: 应该是当插件对应的配置页面更改时触发此方法
3) onUpdate: 此方法就是响应设定的定时更新触发时的消息了,用于更新界面内容。

创建方法:在项目中新建一个类,父类设置为AppWidgetProvider即可

2. AppWidgetProviderInfo对象

AppWidgetProviderInfo对象其实就是一个xml文件,存储在resxml目录下,用于定义组件的宽度、高度、组件内容更新频率、初始化布局等信息,系统会根据这些信息创建并调整组件的显示。下面是一个示例文件:

1) minWidth: 用于设置组件的最小宽度,系统会根据此值计算出插件横向所要占据的网格数量
2) minHeight: 用于设置组件的最小高度,系统会根据此值计算出插件纵向所要占据的网格数量
3) minResizeWidth: 插件缩放时允许的最小宽度
4) minResizeHeight: 插件缩放时允许的最小高度
5) updatePeriodMillis: 插件的更新频率,单位ms,此值小于半个小时的时候将按半小时计算,因为android不允许小插件过于频率的更新以节省资源和电池用量,对于更新频率要小于半个小时的情况,我们会在后面讲述如何处理
6) initialLayout: 用于指定插件所使用的布局文件
7) initialKeyguardLayout: 用于指定在锁屏界面上插件所使用的布局文件
8) configure: 用于指定插件设置窗口所使用的布局文件
9) previewImage: 用于指定添加插件页面中,插件所使用的预览图像
10) resizeMode: 用于指定插件允许的缩放模式,可选择横向、纵向或者不能缩放
11) widgetCategory: 用于指定插件都在哪个地方显示,可选择在桌面、锁屏界面或者搜索界面。

创建方法:在项目中新建一个xml文件,xml文件的类型为appwidget-provider,生成的文件将自动存储到resxml目录下

3、Widget布局文件

  首先来说,它是一个布局文件,和Activity的布局文件一样,存储在reslayout目录下,所不同的是,插件布局中并不支持所有的组件。

  可支持的部局组件如下:

  • FrameLayout
  • LinearLayout
  • RelativeLayout
  • GridLayout

  支持的内容组件如下:

  • AnalogClock
  • Button
  • Chronometer
  • ImageButton
  • ImageView
  • ProgressBar
  • TextView
  • ViewFlipper
  • ListView
  • GridView
  • StackView
  • AdapterViewFlipper

  注意:不可以支持以上组件的子类。

  创建方法:新建一个layout文件

三、使自己的第一个小组件生效

  在创建了上文所述的三个对象后,我们还需要在Android Manifest文件中对WidgetProvider对象进行一下声明,这样才可以在插件管理器中看到我们要创建的插件,所用代码如下:

  receiver 节点中的内容即为对SimpleWidgetProvider的定义,intent-filter和meta-data节点都必须添加上才可以使插件生效。

5月 112015
 

我们可以从以下方面考虑Android应用的优化

  1. 如果广播只针对应用内部发送和接收,使用LocalBroadcastManager进行广播,避免发送系统级的广播
  2. 使用Lint工具检查部局文件的合理性,减少不必要的嵌套,提高应用的性能
  3. 使用monkey和monkey runner进行自动化测试
  4. 优化业务逻辑,减少不必要的操作,如在不必要的时候减少网络的请求
 Posted by on 2015-05-11
4月 272015
 

  获取外部存储路径的代码为:

  这个代码开始在htc、三星等机器上工作正常,但是后来发现在小米、华为等一些机器上不能操作外部存储设置上的文件,本来以为是需要特殊权限的问题,在网上查了半天没查到解决办法。后来才发现,原来并不是机器的问题,而是在创建文件夹的时候调用的函数不对,我是使用mkdir去创建文件夹的,但是mkdir不能创建多层目录,所以就造成了后边的文件不能访问。

  不知道有mkdirs为什么还要有mkdir函数,留着迷惑人啊!