life02

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  197 随笔 :: 3 文章 :: 37 评论 :: 0 Trackbacks

#

       startActivityForResult与startActivity的不同之处在于: 1, startActivity( ) 仅仅是跳转到目标页面,若是想跳回当前页面,则必须再使用一次startActivity( )。
 2, startActivityForResult( )可以一次性完成这项任务,当程序执行到这段代码的时候,页面会跳转到下一个Activity, 而当这个Activity被关闭以后(this.finish()),程序
会自动跳转会第一个Activity,并调用前一个Activity的onActivityResult( )方法。

 

http://www.cnblogs.com/linjiqin/archive/2011/06/03/2071956.html

 

android中使用startActivityForResult回传数据(转)

假设:我这里有两个Activity:A和B,从A中向B中传递数据的时候采用的是Bundle封装数据,然后从A中跳转到B中,当B有需求将数据 封装起来回传给A并跳转回A。那么A中接收数据时还要先判断Bundle是否为空,因为第一次访问A的时候(即B还没有回传的时候),Bundle是为空 的,这样显然是比较麻烦的,不明智的做法。

还好startActivityForResult来做跳转给了我们更好的解决办法。

1.跳转的时候不是采用startActivity(intent) 这个方法,而是startActivityForResult(intent, 0)。

1 Intent intent=new Intent();
2 intent.setClass(A.this, B.class);
3 Bundle bundle=new Bundle();
4 String str1="aaaaaa";
5 bundle.putString("str1", str1);
6 intent.putExtras(bundle);
7 startActivityForResult(intent, 0);//这里采用startActivityForResult来做跳转,此处的0为一个依据,可以写其他的值,但一定要>=0

2.重写onActivityResult方法,用来接收B回传的数据。

1 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
2 switch (resultCode) { //resultCode为回传的标记,我在B中回传的是RESULT_OK
3   case RESULT_OK:
4 Bundle b=data.getExtras(); //data为B中回传的Intent
5   String str=b.getString("str1");//str即为回传的值
6 break;
7 default:
8 break;
9 }
10 }

3.在B中回传数据时采用setResult方法,并且之后要调用finish方法。

setResult(RESULT_OK, intent); //intent为A传来的带有Bundle的intent,当然也可以自己定义新的Bundle
finish();//此处一定要调用finish()方法

这样当B中调用finish方法的时候,跳转到A时会自动调用onActivityResult方法,来获取B中回传的intent了。 
详细的代码不贴了,那纯属浪费时间,网上关于startActivityForResult的全是些转帖的,都是代码,看着真心烦。

posted @ 2011-12-06 21:48 life02 阅读(414) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2011-12-06 16:38 life02 阅读(862) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2011-12-06 11:30 life02 阅读(2955) | 评论 (0)编辑 收藏

google上面下载Android的SDK或者OPhonesdn 下载 Ophonesdk,解压出来后在SDK的根目录下有一个tools文件夹,双击emulator.exe,直接启动模拟器

1.模拟器外观的定制:
480x320, landscape: emulator -skin HVGA-L
320x480, portrait : emulator -skin HVGA-P (default)
320x240, landscape: emulator -skin QVGA-L
240x320, portrait : emulator -skin QVGA-P
2.为模拟器加上SD卡:
emulator -sdcard D:\sdcard.img
下面我们再来说说如何创建"sdcard.img"文件:
“tools”目录下还有另外一个很好用的工具“mksdcard.exe”,一看名字就知道——make sdcard。对,就用它来创建一个“SD卡”。
命令为:
mksdcard 512M D:\sdcard.img
OK,这样一个容量为512M的SD卡就创建完毕了。
使用SDCard:
创建: mksdcard <512M>
(bytes(default),K,M)
连接到模拟器: emulator -sdcard <目录/sdcard.img>
传文件到SDCard: adb push <目录/myaudio.mp3> 3、模拟器的通信
GPhone的模拟器有个特有的号码:15555218135,这个就类似我们实体手机的SIM卡号码啦。

 



正确启动模拟器[SDK 1.5]
安装好JDK后,运行框中输入cmd,回车后就会弹出个黑框。(接下来的大部分操作都是在这黑框下进行的)在黑框中输入cd /d D:/ android-sdk-windows-1.5/tools/
(这个路径是我存放模拟器的路径、大家要根据自己所存放的路径输入相应的路径)
输入完正确的命令后就会自动弹出你所存放模拟器的路径(如上图)
接着在这命令后面输入android并回车,这时黑框中会弹出一堆的命令,看不懂也没关系!我们滚动黑框见到最后一个命令的位置就好
在最后的这个命名后面输入android create avd -t 2 -n g1,并回车。『注意:这个命令中最后一个g1是可以任意取名的,你可以写g2、android、gphone???之类的』
【大家在操作这步的时候,要切记android与create与avd与-t与2与-n与g1之间都是有空格的 】
这时又会弹出个新的命令出来!我们只要输入no并回车就可以了
结束以上的操作之后,打开存放SDK模拟器的文件,找到模拟器的程序右键点击发送——桌面快捷方式
回到桌面后,发现双击那个小绿人发现还是打不开模拟器!先不要着急、右键点击属性!在快捷方式-目标的路径后面加上 -avd g1
再次注意:这个-前面是要空格一下的,avd后面跟着的g1则要跟你在上一步黑框中所输入的名字是一致的
posted @ 2011-12-06 11:13 life02 阅读(265) | 评论 (0)编辑 收藏

   启动Android可以通过Eclipse的Avd与SDK Manager完成,另一种方法是通过命令行来完成模拟器的创建或启动。方法如下:

1. android list target 

该命令显示已安装的android平台,每个平台有自己的id号。

 

2.android create avd -n skwwt -t 11

该命令创建一个新的模拟器,-n后面接创建模拟器的名字,-t后面接平台的id,即(1)中显示的id号。

 

3.emulator @skwwt 或者 emulator -avd skwwt

该命令启动名字为skwwt的模拟器。


     下面是我转的一些关于Android模拟器的使用方法

 

 

     1、Android模拟器介绍

  Android中提供了一个模拟器来模拟ARM核的移动设备。Android的模拟器是基于QEMU开发的,QEMU是一个有名的开源虚拟机项目(详见http://bellard.org/qemu/),它可以提供一个虚拟的ARM移动设备。Android模拟器被命名为goldfish,用来模拟包括下面一些功能的ARM SoC:

  * ARM926ej-S CPU

  * Thumb support

  * MMC

  * RTC

  * Keyboard

  * USB Gadget

  * framebuffer

  * TTY driver

  * NAND FLASH

  Android模拟器所对应的源代码主要在external/qemu目录下。如果你想将Android移植到其他设备上,熟悉它目前所针对的模拟器环境可以提供一些参考。

  对于应用程序的开发者,模拟器提供了很多开发和测试时的便利。无论在Windows下还是Linux下,Android模拟器都可以顺利运行,并且Google提供了Eclipse插件,可将模拟器集成到Eclipse的IDE环境。当然,你也可以从命令行启动Android模拟器。

  这款模拟器功能非常齐全,电话本、通话等功能都可正常使用(当然你没办法真的从这里打电话)。甚至其内置的浏览器和Google Maps都可以联网。用户可以使用键盘输入,鼠标点击模拟器按键输入,甚至还可以使用鼠标点击、拖动屏幕进行操纵。

  当然模拟器毕竟是模拟器,和真实的机子还是存在差别的,

  android模拟器和真机的不同之处:

  * 不支持呼叫和接听实际来电;但可以通过控制台模拟电话呼叫(呼入和呼出)

  * 不支持USB连接

  * 不支持相机/视频捕捉

  * 不支持音频输入(捕捉);但支持输出(重放)

  * 不支持扩展耳机

  * 不能确定连接状态

  * 不能确定电池电量水平和交流充电状态

  * 不能确定SD卡的插入/弹出

  * 不支持蓝牙

  2、创建和启动Android模拟器

  要玩GPhone的模拟器,当然需要先去http://developer.android.com/sdk(如果打不开就用http://androidappdocs.appspot.com/sdk/index.html)上面下载Android 的SDK,解压出来后在SDK的根目录下有一个tools文件夹,里面就是模拟器和一些非常有用的工具。(SDK详细的安装过程请参照 http://blog.csdn.net/magicyu2/archive/2009/11/02/4755747.aspx)

  要正确的启动模拟,你必须先要创建一个 AVD( Android Virtual Device 虚拟设备 )

,你可以利用AVD创建基于不同版本的模拟器,下面就介绍如何创建AVD:

 

  (1) 查看当前支持版本(在列出的版本中我们需要记住id值,这个值在第2步中使用):

  magicyu@magicyu-desktop:~$ android list target

  你可以看到几个Available Android targets,比如:Name: Android 1.6,他们有各自的id号。

  (2) 创建AVD:

  magicyu@magicyu-desktop:~$ android create avd -n magicyu -t 2

  -n后面接需要创建avd的名字,-t后面接需要创建虚拟器的类型,2即为步骤(1)中得到的类型id号。

  (3) 查看是否创建成功(如果成功会显示刚才我们创建的avd信息):

  magicyu@magicyu-desktop:~$ android list avd

  (4) 启动模拟器:

  magicyu@magicyu-desktop:~$ emulator @magicyu 或者

  emulator -avd magicyu

  其中@和-avd后接的是你创建过的avd名字

  (5) 选择启动的皮肤

  magicyu@magicyu-desktop:~$ emulator -avd magicyu -skin QVGA

  skin后面接所要启动皮肤的类型,所有的类型可以在/ platforms/android-1.*/skins目录下找到,*为所指的版本。如在1.6版本的SDK下有HVGA,QVGA, WVGA800,WVGA854几种。按Ctrl+F11,可以直接改变模拟器的横纵摆放。

  当然AVD也可以在Eclipse中创建和启动。关于Eclipse+ADT+SDK的安装请参见http://blog.csdn.net/magicyu2/archive/2009/11/02/4755747.aspx。

  运行Eclipse,Window->Android SDK and AVD Manager,就能得到如下的界面,选择新建即可新建一个AVD。

posted @ 2011-12-06 11:02 life02 阅读(1780) | 评论 (0)编辑 收藏

在SDK的Tools文件夹下包含着Android模拟器操作的重要命令adb,adb的全称为Android Debug Bridge就是调试桥的作用。通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具。

adb的工作方式比较特殊采用Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情況下adb会daemon相关的网络端口,所以当我们运行Eclipse时adb进程就会自动运行。

1.通过adb可以轻松地执行Linux Shell命令,进入设备或模拟器的shell:adb shell就可以进入模拟器的shell环境中。也可以执行各种Linux的命令,其命令格式為:adb shell command
例如:
adb shell dir 就是列举目录,在Linux中根目录为/而不是Windows上的C盘,D盘.
adb shell dmesg 会印出Linux的debug信息。
2.安装apk程序到模拟器

则执行adb install android123.apk,这样名为android123的安裝包就会安裝到Android模拟器中,前提是android123.apk文件需要放到SDK/Tools目录下。
3.向emulator传送文件
使用adb push android123.txt /tmp/android123.txt命令可以把SDK/Tools下的android123.txt文件传送到模拟器的/tmp/文件夾中,需要注意的是/tmp/文件夾中內容会在Android模拟器新啟動時清空
4.从Android模拟器中回传文件到电脑
通过adb pull /tmp/android123.txt android123.txt命令就會把模拟器的tmp文件夾下android123.txt文件回传到电脑SDK/Tools目录下。

继续android adb命令相关介紹,除了可以方便的安裝apk文件、pc和Android模拟器互传资料外还有Android Debug Bridge一些辅助的功能。
1.如果在Eclipse中发现有* daemon not running. starting it now *的提示可以结束adb
adb kill-server

2.显示android模拟器状态
adb devices 端口号等信息,执行后会现实TCP端口号
adb get-product 获取设备型号
adb get-serialno 获取序列号

3.等待正在运行的设备
adb wait-for-device

4.端口转发adb forward adb forward tcp:5555 tcp:1234 实现将默认的TCP 5555端口转发到1234端口上

5.查看bug報告
adb bugreport

posted @ 2011-12-05 20:01 life02 阅读(492) | 评论 (0)编辑 收藏

Android Emulator 備忘指令

發表於 一月 8, 2011 在 Android 分類. 10 則評論

  • Android 模擬器命令列啟動模式

在 android-sdk-windows-1.1\tools 執行 emulator 以執行模擬器
加上-skin參數,指定顯示模式為 HVGA-L,則可轉為橫向

emulator – skin HVGA-L (480*320
,水平顯示)
emulator – skin HVGA-L (320*480
,垂直顯示,模擬器預設模式)
emulator – skin HVGA-L (320*240
,水平顯示)
emulator – skin HVGA-L (240*320
,垂直顯示)

  • 使用 mksdcard 指令模擬 1GB 的記憶卡

mksdcard 1024M sacard.img

  • 模擬插入 SD 卡的模擬器

emulator – sdcard sdcard.img

  • 使用 adb+push 上載檔案到 SD 記憶卡

adb push 001.jpg /sdcard (複製檔案到 /sdcard 目錄下)
adb push pictures /sdcard (
複製 picture 照片目錄到 /sdcard 目錄下)
adb push mp3 /sdcard (
複製 mp3 音樂目錄到 /sdcard 目錄下)
adb shell (Android
模擬器啟動命令列模式)
#cd /sdcard (
進入 /sdcard 目錄)
#ls (
查看 SD 記憶卡中的檔案)

  • 使用 adb+pull 從 SD 記憶卡下載檔案

adb pull /sdcard/001.jpg . (下載 /sdcard 目錄下的檔案)
adb pull /sdcard/pictures . (
下載 sdcard 目錄下的 pictures 目錄)

  • 刪除 SD 卡裡面的檔案

adb shell
#ced /sdcard
#rm 001.jpg (
刪除 SD 記憶卡裡的檔案)
#rm -r * (
刪除 SD 記憶卡裡所有檔案與目錄)

  • Android模擬器影片播放方法

mksdcard 4096M video.img (製作一個影像檔的 SD 記憶卡)
adb push video.avi /sdcard (
從電腦複製影像檔到 SD 卡中)
emulator -sdcard video.img (
啟動模擬器並載入 SD 卡)
下載免費的影片播放軟體,ex: Meridian Video Player (iiivpa.apk)

http://sites.google.com/site/eternalsandbox/Home/meridian-video-player

adb install iiivpa.apk (安裝Meridian Video Player)
接下來就可以用裝上去的player播放.mp4、3gp與.wmv三種檔案格式

  • 安裝 APK 應用程式

adb install filename.apk (安裝filename.apk)
adb install -r filename.apk (
保留已設定資料,重新安裝filename.apk)
adb -s emulator-5554 install filename.apk (
指定安裝 APK 套件在 5554 的 Android 模擬器中)

  • 移除 APK 應用程式

adb uninstall package
adb uninstall -k package (
移除程式時,保留資料)
此package名稱不是安裝APK套裝時的檔名或顯示在模擬器中的應用程式名稱
可以先到/data/data或data/app目錄下,查詢想移除的package名稱
adb shell
ls /data/data
或 /data/app (查詢 Package 名稱)
exit
adb uninstall package (
移除查詢到的 Package)

  • ADB 系統除錯與連結工具

$adb devices (顯示目前有多少個模擬器正在執行)
$adb -s (
指定模擬器來操作)
adb -s emulator-5554 install email.apk
$adb install apkfile (
安裝 APK 應用程式套件)
adb install email.apk
$adb uninstall package (
移除 APK 應用程式套件)
adb uninstall com.android.email
$adb shell (
進入 Android 系統指令列模式)
$ls
$dmesg (
查看 Android Linux Kernel 運作訊息)
ls –
顯示檔案目錄
cd –
進入目錄
rm –
刪除檔案
mv –
移動檔案
mkdir –
產生目錄
rmdir –
刪除目錄 $adb push (複製檔案到 SD )
adb push mp3 /sdcard
$adb pull . (
從 Android 系統下載檔案)
adb pull /data/app/com.android.email
$adb logcat (
監控模擬器運作紀錄,以Ctrl + c 離開監控模式)
$adb bugreport (
產生 adb 除錯報告)
$adb get-state (
獲得 adb 伺服器運作狀態)
$adb start-server (
啟動 adb 伺服器)
$adb kill-server (
關掉 adb 伺服器)
$adb forward tcp:6100 tcp:7100 (
更改模擬器網路 TCP 通訊埠)
$adb shell ps -x (
顯示 Android 上所有正在執行的行程)
$adb version (
顯示 adb 版本)
$adb help (
顯示 adb 指令參數)

  • Emulator 命令列啟動參數

emulator -timezone Asia/Taipei (指定時區)
emulator -no-boo-anim (
省略開機小機器人動畫畫面)
emulator -scale auto (
調整模擬器視窗大小)
emulator – scale factor (factor: 0.1-3.0)
emulator -dpi-device 300 (
更改模擬器的解析度,default為 165dpi)
emulator -skin (
更改模擬器顯示模式)
emulator -help-keys (
顯示鍵盤快速鍵說明)
emulator -shell (
相當於adb shell 功能)
emulator -data data.img (
使 /data 目錄使用 data.img 的檔案空間)
emulator -sdcard sdcard.img (
使 /sdcard 目錄使用 sdcard.img 的檔案空間)
emulator -cache cache.img (
瀏覽器暫存檔儲存空間)
emulator -wipe-data (
使模擬器恢復到原廠設定)
emulator -help (
顯示 emulator 指令參數)

 


posted @ 2011-12-05 19:54 life02 阅读(559) | 评论 (0)编辑 收藏

安装APK文件到Android模拟器

Android手机使用的执行文件为APK格式,类似于Windows平台的exe文件。在Android模拟器中安装APK文件有多种方法,如果 你是开发人员,可以通过Eclipse+ADT,使用DDMS可以传输文件。大多数可以直接在Windows的cmd中操作就可以了。

一、首先在Android SDK的Tools文件夹中找到emulator.exe文件并运行,这时Android模拟器就启动了,

二、 将android123.apk文件复制到Android SDK的Tools目录中(点击下载Android123.apk文件),使用cmd的cd命令定位到Android 模拟器目录Tools中,执行adb install android123.apk命令,这时模拟器将会自动执行安装。 

三、在Android模拟器中可以找到我们安装好的文件-Android手机之家。

四、 用鼠标单击这个文件就可以看到Android手机之家网站的演示程序。 

  写在最后我们可以发现安装Android软件到模拟器很简单,只需要执行adb install命令就可以了,当然其实我们做的是复制文件到Android模拟器的/data/app文件夹,并创建了一个快捷方式。

 

Android sdcard的使用

 

(下面是在linux运行的,而且是在sdcard的镜像文件同一目录下进行操作的)
这两天在实现播放器列表实现,其中需要使用到Sdcard,在网上收集到了一些sdcard的使用,发现几乎都是错误的,最后经过小组几个人的探讨,终于将sdcard使用成功了。下面就将使用sdcard的使用步骤总结下来:
我们在网上会发现,很多人都是这样来操作sdcard的:
1、首先是生成sdcard镜像文件sdcard.img或者是其他的名称。命令为:mksdcard -l sdcard capacity directory
例如:mksdcard 1024M D:\sdcard.img

directory 指的是镜像文件存放的目录,capacity就是要创建的镜像文件的容量。这里将镜像文件放在当前目录下。

2、之后,启动模拟器:emulator -sdcard sdcard镜像文件的目录
例如:emulator -sdcard D:\sdcard.img

3、打开另外一个终端,输入下面命令来将资源放入到sdcard里面
adb push source-file sdcard的镜像文件目录
这个时候会发现这是不能成功的,会得出Read Only System 这样的错误失败提示。
这里,来分析一下为什么会失败。
在 创建sdcard镜像文件的时候,生成的sdcard.img只是一个镜像文件,而不是一个真正的目录,所以如果要将资源文件放入到sdcard的镜像文 件中,当然是错误的,而我们会发现,sdcard是Android中的存储模拟设备,类似于计算机的硬盘一样,这样我们可以向其中放入资源文件,即可以将 命令adb push <目录/audio.mp3> </sdcard/audio.mp3>的镜像文件目录
改为 adb push <目录/audio.mp3> </sdcard.之后,我们进入adb shell中检查是否将文件放入了sdcard中,使用命令adb shell,ls一下,找到sdcard,检查一下sdcard中,这时,sdcard中已经拥有资源了,即我们的push命令运行成功。
以上就是sdcard存储资源的使用。

 

adb命令的使用

adb(Android Debug Bridge)是Android 提供的一个通用的调试工具,借助这个工具,我们可以管理设备或手机 模拟器 的状态 。还可以进行以下的操作:
1、快速更新设备或手机模拟器中的代码,如应用或Android系统升级;
2、在设备上运行shell命令;
3、管理设备或手机模拟器上的预定端口;
4、在设备或手机模拟器上复制或粘贴文件;

以下为一些常用的操作:
1、安装 应用到模拟器:
adb install
比较遗憾的是,Android并没有提供一个卸载 应用的命令,只能自己手动删除 :
adb shell
cd /data/app
rm app.apk
2、进入设备或模拟器的shell:
adb shell
通过上面的命令,就可以进入设备或模拟器的shell环境中,在这个Linux Shell中,你可以执行各种Linux 的命令,另外如果只想执行一条shell命令,可以采用以下的方式:
adb shell [command]
如:adb shell dmesg会打印出内核的调试信息。
3、发布端口:
可以设置任意的端口号,做为主机 向模拟器或设备的请求端口。如:
adb forward tcp:5555 tcp:8000
4、复制文件 :
可向一个设备或从一个设备中复制文件,
复制一个文件或目录到设备或模拟器上:
adb push
如:adb push test.txt /tmp/test.txt
从设备或模拟器上复制一个文件或目录:
adb pull
如:adb pull /addroid/lib/libwebcore.so .
5、搜索模拟器/设备的实例:
取得当前运行的模拟器/设备的实例的列表及每个实例的状态:
adb devices
6、查看bug报告:
adb bugreport
7、记录无线通讯日志:
一般来说,无线通讯的日志非常多,在运行时没必要去记录,但我们还是可以通过命令,设置记录:
adb shell
logcat -b radio
8、获取设备的ID和序列号:
adb get-product
adb get-serialno
9、访问数据库SQLite3
adb shell
sqlite3

10、通过gsm call命令可以像Android 模拟器打电话 ,除了在EclipseADT 的DDMS中通过按钮Dial外,还可以通过DDMS外壳调用gsm call命令直接拨打,我们首先需要启动AndroidEmulator,然后在cmd环境下执行telnet localhost 5554 下面就可以向Android模拟器 拨号,参数为gsmcall < phoneNum> ,比如给10086打电话 为gsm call +10086


posted @ 2011-12-05 19:34 life02 阅读(551) | 评论 (1)编辑 收藏

emlulator可以在运行时与eclipse联起来测试. 但怎么测试己经打好包的apk呢?

何果打apk就先不说了.

 

1 把apk放到emulator里,安装,运行:(avd运行,安装apk)

   运行cmd :

    android-sdk-windows-1.5_r3\tools>adb install snake-sample.apk

  就OK了. 你打开emulator就看到了.

 

2 如何在live-CD里按装apk呢?

 

把apk放到网络上的一个地方, 然后下载(我试图放到hotmail的复件里,但不行, 又放到163的复件里, 也不行,后来我自己起了个tomcat点击下载的). 会下载到sdcard/download/目录下.

把它copy到/data/app就自动按好了.


posted @ 2011-12-05 19:32 life02 阅读(281) | 评论 (0)编辑 收藏

很多初入Android开发的网友向我们问到Context有什么作用,很多地方都用到它,这里Android123给这些新入门的网友做个简单的解释:

   Context字面意思上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄,很多方法需要通过Context才能识别调用者的实例,比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决,主要原因是因为实现Context的类主要有Android特有的几个模型,Activity、Service以及BroadcastReceiver。

  常规需要Context实例的方法主要有各种Service实现的类,比如说SensorManager在实例化时需要getSystemService(String)方法就必须由Context的实例执行,还有一些私有的文件系统I/O比如说openFileInput以及常用的Toast的makeText方法。

在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
比如一个activity的onCreate:
protected void onCreate(Bundle state) {
        super.onCreate(state);

        TextView label
= new TextView(this); //传递context给view control
        label.setText("Leaks are bad");

        setContentView(label);
}
把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。
这样如果context发生内存泄露的话,就会泄露很多内存。
这里泄露的意思是gc没有办法回收activity的内存。

Leaking an entire activity是很容易的一件事。

当屏幕旋转的时候,系统会销毁当前的activity,保存状态信息,再创建一个新的。

比如我们写了一个应用程序,它需要加载一个很大的图片,我们不希望每次旋转屏 幕的时候都销毁这个图片,重新加载。实现这个要求的简单想法就是定义一个静态的Drawable,这样Activity 类创建销毁它始终保存在内存中。
实现类似:
public class myactivity extends Activity {
       
private static Drawable sBackground;
       
protected void onCreate(Bundle state) {
                super.onCreate(state);

                TextView label
= new TextView(this);
                label.setText(
"Leaks are bad");

               
if (sBackground == null) {
                        sBackground
= getDrawable(R.drawable.large_bitmap);
                }
        label.setBackgroundDrawable(sBackground);
//drawable attached to a view

        setContentView(label);
        }
}
这段程序看起来很简单,但是却问题很大。当屏幕旋转的时候会有leak(即gc没法销毁activity)。
我们刚才说过,屏幕旋转的时候系统会销毁当前的activity。但是当drawable和view关联后,drawable保存了view的 reference,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能销毁,它所 引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。gc对这种类型的内存泄露是无能为力的。

避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免由于对象对 activity的引用导致activity不能正常被销毁。我们可以使用application context。application context伴随application的一生,与activity的生命周期无关。application context可以通过Context.getApplicationContext或者Activity.getApplication方法获取。

避免context相关的内存泄露,记住以下几点:
1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
2. 对于生命周期长的对象,可以使用application context
3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化



posted @ 2011-12-05 17:13 life02 阅读(326) | 评论 (0)编辑 收藏

仅列出标题
共20页: First 9 10 11 12 13 14 15 16 17 Last