7C00.ME/houmu 2012-03-01

《Google!Android2手机应用程序设计入门》笔记-1

第一篇 入门篇

chapter 01 初探Android

和其他Android开发教程一样,开篇一般是概要地介绍Android的基本信息,同时也不忘盛赞一番,本书也不例外。这样的好处是,调动读者开发Android应用的激情,无可厚非。每章的结束是参考资料,给出了很多实用的网站链接。这应该属于这本书的写作风格或者说特色之一,即引导读者想办法去解决遇到的问题,因此本书算是一本比较适合自学的书,也名副其实十本入门书。

chapter 02 安装Android开发工具

基本流程,下载所有用到的工具,安装JDK,安装Android SDK,安装ADT for Eclipse。这个过程中基本没有太大的难度,可能最大的问题就是,网速!

chapter 03 管理SDK

这一章体现了本书的另一风格,就是对开发工具讲解比较到位。这一章介绍了Android开发工具架构的演变、下载SDK组件,升级开发工具与SDK组件和删除SDK组件。其实根据SDK提供的GUI就可以很容易的完成这些操作,这一章内容有些多余。

chapter 04 打开现有项目

1、4-1“打开项目”应该是“新建项目”。 2、打开已经有的项目可以通过Eclipse的File->Import,再是General->Existing Projects into Workspace,然后Browse到项目目录,最后Finish即可。这应该输入Eclipse对Java项目管理的一种方式,之前一直没怎么用过Java和Eclipse,算是新学了一招。感觉visual Studio的项目管理方式可能更好一些,也可能是习惯所致,但是作为IDE,Eclipse实在是不能和Visual Studio相比,差得太多了。 3、通过上面打开的项目可能由于sdk版本的问题,会出现红叉,在项目文件夹图标右击选Android Tool,再选Fix Project Properties,可以解决部分问题。有时也可以或需要手动修改项目的project.property文件,改的是sdk版本,或者说api level,这是个人实践心得。

chapter 05 操作Android虚拟机

1、虚拟机运行时的快捷键,暂时记住一组 Ctrl+F12,切换屏幕方向; 2、命令行删除程序,作者用的是 adb shell cd data/app/ rm XXX.XXX.apk 这样直接删除程序报,可能会有遗留问题,不能完成正真的卸载。 其实命令行下用android命令有一个卸载程序的选项。

chapter 06 建立一个Andriod应用程序

主要讲了Android SDK自动生成的应用程序模版的文件组织方式与用途。主要体会是,Java的包管理和文件系统密切相关,这和C和C++,还有C#不太一样,有好处也有不方便的地方,不过和Python有点相似。初入Java的世界,感觉很多地方不太一样。

第二篇 基础篇

chapter 07 描述用户界面

1、Android应用程序模式的简单理解。一般把Android程序分为四种类型,Activity、Intent、Service、Content Provider。就我理解,和通常的程序概念比较相近的是Activity和Service,他们的区别在于Activity生命周期较短,Service可以一直运行;Activity要实现GUI,运行在前台,Service不需要(或许也不能),运行在后台。Intent感觉是一个启动器,或者像进程管理器,用于启动Activity以及Activity之间的通信。Content Provider,目前只接触到访问系统共享的信息,比如联系人,在有些程序里面用不到这个。 Activity类似于桌面程序设计中的一个窗口。程序如果有多个窗口或者窗口内容,就对应有多个Activity。不过同一时间只能在Android手机上显示一个Activity。实现一个继承自Activity的类,就相当于完成了一个“窗口”类的设计。但是要show这个“窗口”,必须在AndroidManifest.xml文件里面注册一个这个Activity,和对应的Intent。在这个Android程序设计中没有Main,也没有MainLoop。这和桌面程序设计差别较大,自己一时没有适应。也有人把Activity比作一个网页,在Android程序设计中也用到了Web开发中的MVC模式。或许可以把Intent理解为Activity作为网页的一个url管理器。之前对MVC也是浅尝辄止,理解也不透彻。有一个暂时不理解的地方就是Activity定义了一个“窗口”类,但却没遇到对这个类的实例化。或许是Intent做了实例化的工作,那么一个Activity类是否只能有一个实例存在,不管处在什么样的生命周期状态?回去还要好好想想。 2、Activity类似于桌面程序设计中的一个窗口。Activity类可以完成GUI的全部工作,包括绘制界面元素、处理用户交互行为等。对应于程序设计,就是一个java文件。这样看,一个最简单的Android应用程序,只要两个文件就够了,一个是继承Activity类的类实现Java文件,另一个是AndroidManifest.xml。当然Java文件要包含在一定的文件目录下。不过Google似乎要开发者尽可能实用MVC模式,因此,Eclipse新建的Android项目按照了MVC的方式组织。一个重要的特征是把界面实现代码分离成了xml,把静态字符串常量给分离成了xml资源。Google在Android的开发中的一些API支持,便宜用MVC的设计模式。 3、用xml设计界面,在Activity类定义文件中通过setContentView(R.layout.xxx)来绘制这样的界面。R.xxx.xxx算是Android对MVC特别支持的一个具体表现吧。 4、这一章用到的组件,一个是LinearLayout,在默认的项目模版中作为Activity界面设计布局的根容器;另一个是TextView,用于显示文本的容器。另外介绍几个组件的属性,android:layout_width、android:layout_height、android:orientation等,在字面上还是比较好理解。前两个的常用值有fill_parent、wrap_content等,第三的常用有vertical、horizon等。TextView的一个属性,android:text=”@string/hello”,这里@xxx/xxx和R.xxx.xxx有异曲同工之效。

chapter 08 设计用户界面

1、android:id=”@+id/height”。为什么用+号,我猜测是对于”@string/hello”这样的访问,是对于有string.xml的文件的,而id.xml则不存在。同时单独弄个id.xml又太麻烦,所以就启用了+这种机制。 2、android:inputType=”number”。这个在有些场合比较实用。具体的就不列举了,用的时候不是非常多,用到的时候再查文档即可。

chapter 09 存取识别符号

这一章讲了android:id、R.java、xml,特别提到了把字符串抽取到xml中,这本书里面还是比较重视对实用MVC的引导的。

chapter 10 解读程序流程

主要讲的内容是是分析一个Activity类的代码文件Bmi.java,逐行讲解,对于没有Java基础的人,这一章是很有用的,不过对于熟悉Java的读者,这一章可能有些多余。几个注意的地方: 1、代码文件通常要导入很多的android库文件,用”import android.xxx.xxx;”这种形式,不过书后面也介绍了Eclipse的快捷键Ctrl+Shift+O来自动导入缺少的库; 2、onCreate方法,这里没有开始讲生命周期,而是放到了后面,或许有其他考虑吧; 3、setContentView方法,应该是包含在android.content库里面,后面还有不少这样的set开头的方法,对应可以去总结一下上下文(context)管理的问题。

chapter 11 完成BMI程序

这一章完成了BMI程序的第一个版本。几个注意的地方:(直接抄原文代码了)

EditText fieldheight = (EditText) findViewById(R.id.height); //如何获取组件对象的引用
double height = Double.parseDouble(fieldheight.getText().toString()) / 100; //获取组件的值

Button button = (Button)findViewById(R.id.submit);
button.setOnClickListener(calcBMI);
private OnClickListener calcBMI = new OnClickListener(){
 public void onClick(View v){
...
 }
};

TextView fieldsuggest = (TextView)findViewById(R.id.suggest);
...
fieldsuggest.setText(R.string.advice_heavy);

第三篇 中级篇(一)

chapter 12

这一章重点是MVC模式,具体在实践上,采取了这样的做法:

  1. 把所有的”声明与查找界面组件“(findViewById)的代码,提取到findViews里面;
  2. 把所有的“为特定界面组件添加控制流程”的代码,提取到setListeners里面;
  3. 在onCreate方法里面调用findViews和setListeners,实现程序逻辑和界面组件的声明分离

chapter 13 加入对话框(Dialog)

1 对话框的一种实现代码示例:

private void openOptionsDialog(){
 new AlertDialog.Builder(Bmi.this).
 .setTitle(R.string.about_title)
 .setMessage(R.string.about_time)
 .setPositionButton("确认",
 new DialogInterface.OnClickListener(){
 public void onClick(
 DialogInterface dialogInterface,int i){
 }
 }) 
 .show();

说明:

a. 这里使用了匿名的实体这种方法,据说是这样做的好处是,“当运行完这个对话框后,系统会自动回收这个匿名实体所占用的内存空间。”; b. Bmi.this是对话框所在Activity类的实例的引用; c. 这个对话框里面有个“确认”按钮。

2 添加监听对象的一种方法示例:

在Button的xml里面加上android:onClick=”openOptionsDialog”,还要定义下面形式的函数public void openOptionsDialog(View target){}

3 显示Toast的代码示例

Toast.makeText(Bmi.this,"BMI计算器",Toast.LENGTH_SHORT).show();

4 错误处理

使用try…catch…的异常处理机制。

chapter 14 查看在线内容(URI)

1 给对话框增加一种按钮,具体代码在上文的setPositionButton方法后面插入这样的方法:

.setNegativeButton(R.string.homepage_label,
    new DialogInterface.OnClickListener(){
        public void onClick(
            DialogInterface dialoginterface,int i){
            ......
        }
})

这个本来应该是添加取消按钮的(Negative和Positive相对),作者把它用作了访问首页链接的一个按钮。

2 打开连接、电话、地图的方法示例

Uri uri = Uri.parse("http://sites.google.com/site/gasodroid");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);

上面是打开网页链接的(启动默认浏览器吧); 把parse的参数改成“geo:25.047192,121.516981”,则会启动Google Map定位到指定的坐标; 把parse的参数改成“tel:12345678”,,ACTION_VIEW改成ACTION_DIAL,则会拨号。 个人感觉,上面的代码也可以用匿名实体重写一下,形如:

startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(target));

chapter 15 加入菜单(Menu)

加入菜单,主要实现两个函数,一是onCreateOptionsMenu,另一个事 onOptionsItemSelected,示例如下:

protected static final int MENU_ABOUT = Menu.FIRST;
protected static final int MENU_QUIT = Menu.FIRST+1;

@Override
public boolean onCreateOptionsMenu(Menu menu){
    menu.add(0, MENU_ABOUT, 0, "关于...").setIcon(android.R.drawable.ic_menu_help);
    menu.add(0, MENU_QUIT, 0, "结束").setIcon(android.R.drawable.ic_menu_close_clear_cancel);
    return super.onCreateOptionsMenu(Menu);
}

public boolean onOptionsItemSelected(MenuItem item){
    switch(item.getItemId()){
    case MENU_ABOUT:
        openOptionsDialog();
        break;
    case MENU_QUIT:
        finish();
        break;
    }
    return super.onOptionsItemSelected(item);
}

前一个方式是建立菜单的,后一个是处理选项动作的。另外这里用了andriod.R.xxx.xxx的资源引用方式,是引用系统内置资源的,和R.xxx.xxx区别是前面多了个”android.“。

chapter 16 定义Android列表(Manifest)

实际上这一章对manifest清单文件讲解的不是很清楚。宏观上看,这本书适合作为学习Android的第一本书,但不能作为唯一一本书。

第四篇 中级篇(二)

chapter 17 加入新活动(Activity)

Activity的基本管理,个人总结如下。

1 新建。新建一个继承自Activity的类,实现(Override)onCreate等方法,一般还要添加用于布局等的xml文件,并用setContentView来关联这些xml文件。然后还要在AndroidManifest.xml文件中添加一个Activity节点,基本属性可以仿照默认的Ativity的属性来设置,这称为注册吧。这样就新建了一个Activity。

2 启动。使用Intent,示例代码:

Intent intent = new Intent();
intent.setClass(Bmi.this, Report.class);
startActivity(intent);

上面代码是要启动类名是Report的Activity。

3 Activity间数据传递,使用Bundle

发送方的示例代码,在上面启动代码的startActivity之前,加上这样的代码:

Bundle bundle = new Bundle();
bundle.putString(”KEY_HEIGHT",field_height.getText().toString());
...
intent.putExtras(bundle);

接收方的示例代码,一般在onCreate方法里面来接受前一个Acitity传来的数据:

Bundle  bunde = this.getIntent().getExtras();
double height = Double.parseDouble(bunde.getString("KEY_HEIGHT"))/100;

这样height的值就是前面field_height.getText().toString()的值。 在这里的Bundle就像是一个非常只能的字典。

chapter 18 传送数据到新意图(Intent)

前面一并整理了。

chapter 19 信息提醒

protected void showNotification(double  BMI){
    NotificationManager barManager = (NotificationManager)
        getSystemService(NOTIFICATION_SERVICE);
    Notification barMsg = new Notification(
        R.drawable.icon,
        "欧,你过重啰!",
        system.currentTimeMillis()
    );
    PendingIntent contentIntent = PendingIntent.getActivity(
        this,
        0,
        new Intent(this, Bmi.class),
        PendingIntent.FLAG_UPDATE_CURRENT);
    barMsg.setLatestEventInfo(
        Report.this,
        "你的BMI值过高",
        “通知监督人”,
        contentIntent
    );
    barManager.notify(0,barMsg);
}

chapter 20 记录与差错(Log)

1 Log.d(TAG, “find Views”)

2 虚拟机上的查错设置: DevTools -> Developer Settings -> Show CPU Usage

chapter 21 活动的生命周期(LifeCycle)

这章计划单独研究一番。

chapter 22 存储信息(Preference)

1 存储偏好设置

@Override
 
public static final String PREF = "BMI_PREF";
public static final String PREF_HEIGHT = "BMI_HEIGHT";
 
protected void onPause() {
    super.onPause()
    SharedPreference settings = getSharedPreferences(PREF,0);
    settings.edit()
        .putString(PREF_HEIGHT, field_height.getText().toString())
        .commit();
}

在Activity的Pause之前存储部分数据是比较合适的。

2 取得偏好设置

private void restorePrefs(){
    SharedPreference settings = getSharedPreference(PREF,0);
    String pref_height = settings.getString(PREF_HEIGHT,"");
    if(! "".equals(pref_height)){
        field_height.setText(pref_height);
        field_weight.requestFocus();
    }
}

chapter 23 加入单元测试

和21章一样,要专门研究一番,书上给出了单元测试的一种方法。

chapter 24 开发不息

这一章是个过渡章节吧,主要是引出下一篇。