Pro Android 4 第二章 创建Android开发环境

译者注:
本章主要是讲解如何搭建eclipse开发环境。由于出书比较早,内容有些过时,所以暂不翻译此部分内容,而是由译者直接提供最简答的方法进行配置。然后再接着翻译剩余部分内容。

      Android 开发环境搭建

     以前开发android需要自己搭建eclipse环境,自己下载sdk,adt,对于初学者比较繁琐。于是google最近将这个开发环境已经集成在一起,可以直接点击下载。下载完成后,直接打开即可,不需要做任何配置。      
访问http://developer.android.com/sdk/index.html
点击如下所示图标,即可下载最新的集成开发环境。

     

     另外,在相同页面,还有Android Studio的下载链接,后续google为Android开发提供了专门的IDE,可以想象以后Eclipse将逐渐被Android Studio取代。

     注:下面将继续翻译本章内容:


     了解一下Android的基本组件

     任何一个应用框架都会有一些关键的组件,用户了解了这些组件的基本含义有助于在此应用框架下开发应用。例如:你需要了解javaServer pages(jsp)和servlets才能编写J2EE(java 2 enterprise edition)平台上编写程序。同样,档你创建一个Android应用时,你也需要理解Views,activities、fragments、intents、content providers、services和AndroidMenifest.xml文件。下面简要介绍一下各部分,后续章节会仔细介绍。

      View
     Views是组成用户交互界面的基础的UI元素。View可以是一个按钮、一个标签、一段文字或者其他的UI元素。如果你很熟悉J2EE和Swing,那么你就很好理解Android中的view。Views也可以是一个层次结构,可以包含其他的view。简而言之,你所看到的一切都是view。

      Activity

     activity是一个UI概念,通常情况下表示一个单独屏幕。一般情况下,会包含一个至多个View,但是View并非必需。Activity更像是它的名字所表示的意思——让你通过activity来做某些事情,这些事情可以是浏览数据、创建数据和编辑数据。大多数应用都或多或少含有activity。

     Fragment

     当屏幕太大时,在一个activity钟就很难所有的功能。而Fragment更像是一个子activity,而一个activity可以同时显示多个fragment。而小屏幕通常只有一个fragment,这个fragment的表现和大屏幕中的一样。

     Intent

     Intent通常定义了某种做事的“意图”。Intent包含很多概念,因此最好的方式是通过使用intent的例子来理解.你可以通过Intent来进行如下活动:

     广播一条消息。

     启动一个服务。

     显示一个网页或联系人列表。

     拨打电话号码或者接听电话。

     Intent并非只是由你自己的应用进行初始化,系统也会使用Intent向你的应用发送特定消息,如短信接收通知。

     Intent可以是显示的,也可以是隐式的。如果你仅仅简单的说向浏览某个ulr,系统会自动填充好intent。你还可以决定由什么来处理这个intent。Intent使动作和动作句柄实现了松耦合。

     Content Provider

     在手机上,数据共享式很平常的。为此,Android为应用共享数据定义了一套标准的实现机制,从而不必暴露底层存储、数据结构和相关实现。通过Content provider你可以从其他应用获取数据。

     Service

     Android中的service与Windows和其他平台的service类似,都是后台进程,可以运行很长时间。Android定义了两种类型的service:本地service和远程service。Local service只能有所在应用进行处理。对应的Remote Service是由其它应用调用。一个service的例子就是e-mail应用用来查询是否有新邮件。这种service如果不被其它应用调用,那么可以实现为Local service。而如果其它应用也要调用,则要实现为Remote Service。

      AndroidMenifest.xml

     AndroidMenifest.xml与J2EE里的web.xml类似,用来定义你应用的组件和行为。例如,里面会罗列出你应用中的activity和service,另外还有你的应用特征和所需权限。

     Android虚拟机

     Android Virtual Device可以让用户在上面测试应用程序,而不必使用真机(手机或者平板)。AVDs可以以不同的方式创建从而模拟不同的设备。

     Hello World!
          
     现在你要开始你的第一个Android应用程序了。从创建一个“Hello World”工程开始。通过以下几步来创建应用程序的框架:

     1、启动Eclipse,点击File-new-project。在新建工程对话框里选择Android。下一步你将会看到新建Android工程对话框,如图2-6所示(Eclipse有可能加入了新建Android工程,如果有的话直接用即可)。工具栏里也有一个新建Android工程按钮。

     

     2、如同2-6所示,输入“HelloAndroid”作为工程名。你需要将你的工程做到与众不同,因此需要起一个有意义的名字,这样在eclipse中就可以方便找到这个工程。同时需要注意,默认的工程路径在workspace下。这样,如果你的workspace路径是c:\android,则工程路径为c:\android\HelloAndroid。

     3、暂不理会location选项,因为我们现在先使用默认路径。

     4、下一个窗口显示你可用的编译目标。选择Android 1.6.这个就是你应用所选用的Android版本。你可以讲你的应用运行在Android 2.1 和2.3上,但是但是1.6已经具备你所需要的所有功能,因此选择1.6即可。一般情况下,选择版本最低的,因为高版本的设备可以运行低版本的程序。点击next进入最后一个导示图。

     5、输入Hello Android作为应用名称。这个名字连同应用图标会显示在标题栏处以及应用列表里。名字应该是一个描述性的,但是不要太长。

     6、用com.androidbook.hello作为包名。你的应用必须有一个基础包名,本例就是这个名字。这个包名是你应用的身份证,必须与其他的应用不同。因此,你应该把你自己的域名作为包名的前缀。如果你还没有域名,请起一个与众不同的名字。然而,不能使包名以com.google、com.android、com.example开头,因为这些域名被google限制,你无法上传到应用市场上。

     7、输入HelloActivity作为Activity的名字。你需要告诉Android这个Activity在你的应用启动时需要运行的。你应用中有可能有很多Activity,但是这是第一个被启动的Activity。

     8、最小SDK版本4表明你的应用需要时Android 1.6或者更新的版本。技术上讲,你可以将最小SDK版本设置的比Build Target小。如果你应用调用一些旧版本并没有的功能,你需要巧妙的进行处理,不过这是可以完成的。

     9、点击finish按钮,ADT将会为你生成工程的框架。现在打开src文件夹下的Hello Activity.java文件,编辑onCreate方法,如下所示:

     

     你可能需要import anroid.widget.TextView来消除Eclipse的出错提示,然后保存文件。

     运行程序,需要创建一个Eclipse的启动配置,同时你需要一个虚拟机来运行程序。后面很快会介绍AVDs。Eclipse的启动项配置过程如下:

     1、选择Run--Run Configuration

     2、在对话框双击Android Applic,向导会创建一个新的配置,命名为new configuration。

     3、重命名为RunHelloWorld

     4、点击Browser按钮,选择helloAndroid 工程。

     5、点击运行,如图2-7所示:

     

     6、点击apply--run。你已经很接近了,eclipse开始运行应用程序,但是你还需要一个设备来运行此程序。如图2-8所示,警告你没有兼容的设备,是否需要创建一个。点击是即可。

     

     7、现在会出现一个窗口展示出已经存在的虚拟机(如果2-9)。你需要为应用创建一个合适的虚拟机。点击new


     8、填写图2-10表格。命名为GingleBread,选择Android 2.3.3 - API level 10(也可以选其他版本)。设置SD为10(10M)。使能抓图功能,使用默认皮肤。点击创建AVD。管理器有可能需要你最后确认是否创建。然后点右上角的x退出管理器。

     
     注:你虽然选择的是更新版本的虚拟机,但是你的应用仍然可以运行。因为anroid但是向下兼容的。相反则不行,比如更新的应用无法运行在就版本的虚拟机上。

     9、选择底部列表的虚拟机,有可能需要点击刷新来更新列表。

     10、Eclipse然后就可以运行你第一个android应用程序了。见图:2-11

     

     注:模拟器可能需要一段时间来模拟设备的启动过程。一旦系统启动完成,你会看到锁屏界面。点击menu按钮或者活动解锁图标来解锁。然后你会看到HelloAndroidApp已经运行,正如图2-11所示。请注意模拟器在启动过程中有可能在后台运行其它应用,因此你可能时不时看到一些告警或错误提示。如果遇到,可以忽略进行下一步动作。例如,你运行模拟器,看到一条信息”application abc is not responding“。你可以简单的等着应用开启,或者让模拟器强行关闭应用。一般只要等一会即可。

     现在你已经知道如何创建一个应用程序并使其运行在模拟器上。下面你会更进一步了解模拟器的细节,以及如何使用真正的设备。

     Android虚拟设备

     虚拟机代表了一种硬件规格,例如你可以创建一个虚拟机来模拟一款很老的Android1.5,仅有32M内存卡的设备。其主要目的是当你进行测试时,可以指定一个应用所支持的版本,并创建一个相应版本的虚拟机进行测试。指定或者更改虚拟机非常容易,方便在不同的配置下进行测试。之前,我们已经告诉你如何用eclipse创建一个虚拟机。你可以通过eclipse的Window--AVD Manager来创建虚拟机,也可以如下采用命令行的形式创建。

     使用sdk/tools目录下的批处理文件android.bat来创建和管理已经存在的虚拟机。例如,你可以浏览虚拟机、移动虚拟机等。
     
     默认情况下,虚拟机存储在你home目录(所有平台windwos、linux等均是如此)的.android/avd文件夹下。如果你为刚刚完成的Hello World应用创建一个虚拟机,你就可以在该目录下看到。如果你想在其他地方储存或操作虚拟机也是可以的。如果我们想把虚拟机放在c:\avd下可以按下面操作进行。首先,需要创建一个文件夹c:\avd,下一步是列出你所有可用的Android虚拟机设备,命令如下:
     
     android list target

     这个命令的结果是已经安装的Android版本的列表,每一项都有一个id。然后再次使用命令行工具,输入以下命令:
     
     android create avd -n CupCakeMaps -t 2 -c 16M -p  c:\avd\CupCakeMaps\

     其中:-t后面加上ID号,表示虚拟机的版本,-p后面加入想要存放的位置。
     
     参数的具体含义如下:

     n: 虚拟机名称
      t:目标运行时id。使用android list target命令列出所有的id
     c:sd卡大小(byte)。使用K表示kb,M表示MB
     p:  虚拟机的存储路径,可选
     A:使能抓屏。可选项。在后面”运行模拟器“章节详细介绍

     通过执行命令可以创建虚拟机,你应该可以看到与图2-2类似的输出。当输入命令启动虚拟机时,可能会弹出对话框询问是否创建硬件分析文件。现在我们先选择no。如果选择了yes,将会让你进行一系列配置包括屏幕尺寸,是否有摄像头等等。

     

     即使你指定了一个不同路径存储虚拟机,android命令也会在home目录.android/avd下创建一个CupCaseMaps.ini文件。这样做是很有好处的,比如,如果你再使用eclipse时,可以在Window--AVD Manager下找到刚刚创建的虚拟机。这样你在eclipse中运行程序时,可以选择其中的任何一个。

     再看一眼图2-2,每个版本都对应这一个API level。android1.6对应level 4,android 2.1对应level 7。这些level值与之前的id号没有关系。所以,你必须总是通过android list target来列出id,然后进行创建虚拟机。

     在真机上运行

     测试一个应用的最好方法是在真机上运行。任何商业发布的机器都应该在连接你的工作站时正常工作,但是你也需要做一些小的设置。如果你用的是Mac,那么你无需做任何设置,只需要用USB线将其连接到你的电脑。然后在手机上选择设置--开发者选项--使能USB调试。在Linux机器上,你很有可能需要修改文件:etc/udev/rules.d/51-android.rules.我们将该文件的拷贝防止了我们的网站上;复制其到合适的位置,修改用户名和组名。然后你连接一个Android设备,就可以被发现了。最后,打开手机上的USB调试功能。

     对于Windows系统,你需要安装USB驱动。google提供了一些驱动,放在了子目录usb_driver下。其它的设备生产商也提供了相应的驱动,可以去其网站上下载。当安装好驱动,打开手机上的USB调试功能就可以继续了。

     现在,你的手机已经和工作站连接好了。如果你启动你的应用,则应用有可能直接在设备上启动,或者弹出一个选择框,让你选择使用模拟器还是手机(如果模拟器已经打开)。如果都不是的话,你需要编辑Run Configuration来手动选择目标机器。

     解析Android应用程序的结构

     尽管Android的应用程序的大小和复杂度不受限制,但是其基本架构还是一样的。图2-13展示了你创建好的Hello World工程。

     

     Android应用程序中,某些结构是必须的,而一些是可选的。下表对Android应用中的要素进行了总结:

     
基本元素描述是否必须
AndroidManifext.xmlAndroid应用程序的描述性文件。这个文件定义了Activites、content providers、Services,intent revcier等内如。你也可以声明应用所需要的各种权限,以及授权其他应用使用自己的service。甚至可以包含一些指令细节,可以测试本应用或其他应用
src应用程序所包含的所有源文件
assets文件夹或文件的二进制集合
res应用所包含的资源文件。其子目录包括values、bitmap、drawable、menu、anim、layout、xml和raw
drawable包含图像或者图像描述文件
animator用来描述动画的xml文件,就版本较anim
layout包含应用的view文件。你应该使用xml文件创建view而不是在代码中
menu包含描述菜单的xml文件
values包含了其余的资源文件,例如strings,arrays,styles和colors
xml包含应用使用的额外的xml文件
raw包含应用所需的额外的数据,很可能不是xml文件


从表中可以看出,一个Android应用通常含有三个部分:一个应用程序描述文件,一系列应用程序所需的资源文件,已经应用程序的源码。如果暂时撇开AndroidMenifests.xml不谈,你可以认为Android应用程序就是通过代码来完成事物逻辑,其余的都是资源。其基本结构域J2EE应用程序的架构类似,其资源文件类似于JSPs,事物逻辑类似于servlets,而AndroidMenifest.xml则类似于Web.xml。

     你也可以比较一下两者的开发模型。在J2EE中,创建视图的哲学就是通过标记性语言(Marking Languages)。Android同样采用了此做法,只不过在Android中标记性语言是xml。这样做你可以不必再应用中通过编码来生成视图,而是可以通过编辑xml文件来获取对视图更直观的感受。

     关于资源文件的限制也是值得一提的。首先,Android只支持线性的文件结构,且需要存放在已经定义好的res文件夹中。例如在layout文件夹下,不支持嵌套的文件夹。(res其他的文件夹也是如此)。第二、对于assets和raw文件夹有部分内容是重复的。两者都可以包含原始文件,但是在raw文件下的内容可以视为资源,而assets里的却不可以。所以raw文件夹下的文件可以被本地化,通过资源id进行索引。而assets里的文件却被视为普通文件,不受限制也不被支持。注意,由于assets里的文件不被视为资源,因此可以防止任意数量与层次的文件夹。(第三章讲述的更多的是资源)。

     注:你可能注意到了,在Android中XML使用的非常频繁。这是一种臃肿的数据格式,因此就面临一个问题:当你知道你的程序是运行在一个资源有限的设备中,那么xml文件的存在是否合理?事实上,你在开发过程中编写的xml文件被Android Asset Packeting Tool(AAPT)编译成为二进制文件。因此当你应用被安装在设备上时,这些文件是以二进制数据存储的。当这些文件在运行时需要时,会以二进制格式读取,而不会转换为xml格式。这样,其实你就获取了双方的优势:既可以用xml进行开发,又不必担心它占用宝贵的资源。

     研究一下Android应用的生命周期

     Android应用程序的生命周期由操作系统本身进行严格的管理,基于用户的需要、可用资源的限制等多方面内容。例如,用户想打开一个浏览器程序,而最终的决定权在操作系统上。尽管最终的决定权在系统,但是系统遵循着已经定义好的,有一定规律的指导原则来决定应用程序何时装载、何时暂停何时停止。如果用户正在与一个Activity进行交互,则系统会赋予该应用一个高的优先级。相反的,如果一个应用不可见,系统认为需要关闭该应用以释放更多的资源,则系统会将低优先级的应用关闭。

     将这些与基于网页的J2EE应用生命周期相比,J2EE应用的管理较为宽松。例如,J2EE的容器可以在预见应用在一定时期内处于空闲状态时将应用移除。然而,一般情况下该容器并不会将应用从内存中移出或移入。J2EE容器通常拥有足够多的资源运行多个应用。而对于Android来说,由于资源有限,因此系统需要对应用拥有更强大的管理权。

     注:每一个Android应用程序都运行在一个独自的进程中,都拥有各自独立的虚拟机。这样,对内存进行了有效的保护。通过把不同的应用放到不同的进程中,系统可以知道哪些进程可以拥有更高的优先级。例如一个后台的正在对CPU脉冲计数的进程不可能阻塞一个来电进程。

     Android应用的生命周期是Android中的一个重要概念。由于Android的应用架构师组件化的,这样有利于丰富用户体验,实现无缝复用、快捷的集成。但是这样增加了应用生命周期管理器的任务的复杂度。

     我们来设想一个典型的常见。用户正在打电话,而且需要打开email来回答一个问题。用户点击home键、打开email应用,点击一封邮件,然后通过阅读网上的股票报价回答朋友的问题。这个场景需要四个应用:一个home应用、一个电话应用,一个email应用以及一个浏览器应用。当用户从一个应用切换的另一个应用,用户体验的连贯的。而在后台,系统负责存储应用的状态。例如当用户点击email里的一个连接时,系统负责在运行浏览器应用之前保存email应用中的数据。事实上,系统会在Activity跳转到另一个Activity之前保存所有的元数据信息,以便用户可以回到原来的界面(例如按back键)。如果内存吃紧,系统可能会关掉进程,并在需要时重新启动该进程。

     Android对应用的生命周期及其组件极为敏感。因此,你需要理解并合理安排生命周期时间以得到一个稳定的应用。运行你应用程序的进程会经历各种生命周期事件,为此,Android提供了回调函数供你来处理不同的状态变化。对于初学者,你应该非常熟悉activity中的生命周期回调函数(见清单2-1):

     Listing 2-1 Activity生命周期函数

     protected void onCreate(Bundle saveInstanceState);
     protected void onStart();
     protected void onRestart();
     protected void onResume();
     protected void onPause();
     protected void onStop();
     protected void onDestroy();
               
     清单2-1列举出来在activity生命周期中会调用的方法。理解这些方法合适会被调用对于编写一个稳定的应用程序是非常重要的。注意,你无需重写所有的方法,如果重写,需要同时调用父类的方法。图2-14展示了这些方法的状态机:

     
     
     Android系统可以根据所发生的时间来开始结束activity。当一个activity初次创建时,Android会调用onCreate()的方法。onCreate()方法永远紧跟着onStart方法但是,onStart方法并非只能在onCreate后面,因为当activity被stop后也可以调用onStart。当调用onStart时,你的activity还不可见,不过已经将要可见了。onResume在onStart之后调用,此时activity已经处于前台可以与用户交互了。

     当用户决定跳转到另一个activity,系统会调用onPause方法。而之后,可能调用onResume也可能调用onStop方法。如果用户又回到了原来的页面,则会调用onResume方法。如果你的activity已经变的不可见,则会调用onStop方法。如果你的activity在调用onStop方法后又回到了前台,则会调用onRestart方法。如果你的activity在activity栈上且对用户不可见,当系统决定杀掉你的activity时,会调用onDestroy方法。

     所描述的activity状态模型或许有些复杂,不过,你无需处理每一个状态。大多数情况下,你只需处理onCreate,onResume,onPause即可。通过onCreate来创建用户界面,将数据绑定到你的widgets,设置UI部件的触发事件。在onPause方法中,存储关键数据。这个是在你的应用被系统杀死之前的最后一个安全的方法(必然会被调用的)。onStop和onDestroy不建议使用,所以不要过于依赖这两个方法。

     简而言之,系统管理着你的应用,它可以在任意时候开始、停止、重启你的应用。尽管系统控制着你的组件,但是并不意味着你的组件的运行不受你应用的控制。换而言之,如果系统启动了你应用的一个activity,你就可以在该activity里使用应用的上下文。

     到目前为止,你已经浏览了创建一个新的应用的基本方法、Android应用程序的基本架构以及一些其它Android应用里通用的特征。但是你还不知道当应用出问题时该如何解决。本章最后一部分介绍如何进行调试。

     简单调试

     Android提供了一系列工具来实现调试功能。这些工具集成在Eclipse中。图2-15显示了其中一部分:


     其中一个你会一直使用的工具就是logcat。该工具可以输出使用android.utils.log打印的代码、系统异常和system.out.print输出等。尽管system.out.println可以使用并且可以在Logcat窗口输出,但是还是建议你使用android.util.Log类。该类可以输出提示级别(I)、警告级别(w)和错误级别(E)等多个级别log,以便用户筛选log信息。例如:

     Log.v("String TAG", "This is my verbose message to write to the log");

      这个例子使用Log类中的静态方法v(),当然还有其他的严重级别。你应该选择恰当的严重级别,通常情况下不建议在开发过程中选用v级别的log表示。记住日志会占用cpu和系统资源。

     Logcat的一个好处在于不仅使用虚拟机可以看到log,当使用打开debug开关的真机时也可以讲log输出到日志窗口。事实上,log日志早已存储在设备中,这样在断开连接时,你也可以检索到有用的log。当你再次连接手机和工作站时,你会看到最新的几百条log日志打印在日志窗口上。第11章会介绍高级调试方法。

     启动模拟器

     通过前面介绍,你已经知道如何在eclipse中启动模拟器。通常情况下,你需要先启动模拟器,然后再开发和测试应用程序。想在任意时刻运行模拟器,你需要启动Android SDK目录tools下的AVD Manager或者通过eclipse的窗口菜单。打开管理器后,选择合适的虚拟机,点击start即可。

     当你点击start按钮,会弹出如图2-16的窗口。该窗口可以让你选择模拟器的尺寸,已经开始和关闭的选项。当你使用小的或者中等尺寸的虚拟机,你可以使用默认的尺寸。但是对于大尺寸或者超大尺寸(如平板),默认的尺寸可能在显示效果上差强人意。如果这样,可以使能“Scale Screen to Real Size”选项,并输入尺寸值。这个标签可能会误导用户,因为平板的分辨率可能与你工作站并不相同。以我们的工作站的屏幕为例,当模拟一个尺寸为10英寸的Honeycomb平板时,10英寸对应的缩放倍率是0.64,因此工作站显示的尺寸会比10英寸大一些。因此,建议根据你屏幕尺寸和分辨率选择合适的值。

     

     通过选择,你可以使能快照功能。如果保存快照,可能子在退出模拟器时,造成一定程度的延时。正如其名字所示,进行快照需要你把模拟器的状态写进镜像文件中,这样下次你在启动模拟器时,就可以避免在从头启动Android了。这样,如果快照之前已经存在的话,启动会非常快,节省了退出时耽误的时间,而且会直接恢复到你退出时的状态。

     如果你想重新启动,可以选择“Wipe user data”选项。你也可以取消“Launch from snapshot”来重头启动Android。或者你也可以选择创建一个你喜欢的快照,当再次开启时仅使能“Launch from snapshot”选项,这样会重复使用该快照,而且启动和退出都非常快。快照文件和其它的虚拟机文件存储在相同的位置。任何时候,你都可以编辑、使能这些虚拟机。

     参考文献

     下面是一些有用的参考信息:


     http://developer.htc.com:htc提供的Androd开发者网站。

     http://developer.android.com/guide/developing/tools/index.html:之前所介绍的Android的调试工具说明文档。
     
     www.droiddraw.org:该网站提供通过拖拽ui控件实现android的ui布局的通过。     

     总结

     本章涵盖了一下内容来帮助你进行android应用程序开发:

     下载安装JDK、Eclipse和Android SDK。
     修改环境变量,启动命令窗口。
     安装ADT,已经如何升级ADT。
     views、activities、fragments、intents、content providers、services和AndroidManifest.xml等概念介绍。
     可以用来测试Android应用程序的虚拟机AVD。
     创建Hello World工程,并运行在虚拟机上。
     初始化一个应用的基本要求(工程名称、Android target、应用名称、包名、主Actiivity,最小SDK版本)。
     如何进行运行时配置。
     通过命令行创建AVDs。
     连接真机到工作站上,并运行程序。
     Android应用的内部结构,activity的生命周期。
     可以显示应用调试信息的Logcat。
     运行模拟器的选项介绍,例如快照和调整尺寸。
     
     问题理解
     自我提问下面问题,来巩固本章所学的知识点:
     1、开发Android应用需要jre还是jdk?
     2、你可以不使用eclipse开发android应用吗?
     3、Android SDK目录下tools目录和platform-tools目录有何区别
     4、Android中view的概念是什么?
     5、Intent是什么?
     6、应用的build target必须与minimum SDK相同吗?
     7、当选择一个应用的包名时需要注意什么?
     8、AVD是什么,有什么用?
     9、AVD的快照功能是什么,怎么用?
     10、应用所需的mp3文件需要放在哪个目录下?
     11、应用的图标文件在哪显示?
     12、activity中第一个回调函数是什么?
     13、activity中最后一个回调函数是什么?
     14、哪个类可以像你的应用写日志?
     15、都有哪些方法可以写日志,区别是什么?
     
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值