`

Android的一本很好的英文原著Andbook 我手动将其翻译了 方便以后查阅

 
阅读更多

andbook!

release.002

title_skateboard.png

Android Programming

with Tutorials from the anddev.org-Community.

written by Nicolas Gramlich

Check for the latest version on

http://andbook.anddev.org


Content

Foreword / How to read this doc ................................................. 5

Introduction................................................................................ 6

What is Android – a GPhone? ...................................................... 7

Android from above ........................................................................ 8

Openness ....................................................................................................... 8

All applications are created equal ................................................................. 9

Breaking down application boundaries ......................................................... 9

Fast & easy application development ........................................................... 9

The first weeks .............................................................................. 12

Dalvik.equals(Java) == false ........................................................... 13

Differences to a normal JavaVM ................................................................. 13

The Android Code Challenge ..................................................... 14

Creating Android Applications .................................................. 15

Anatomy of an Android Application ............................................... 15

Activity ......................................................................................................... 15

Intent Receiver ............................................................................................ 17

Service ......................................................................................................... 17

Content Provider ......................................................................................... 18

Android User Interfaces ................................................................. 19

Hierarchy of Screen Elements ..................................................................... 19

Comparing Android UI Elements to Swing UI Elements .............................. 22

The AndroidManifest.xml ......................................................... 23

General ......................................................................................... 24

<manifest> ................................................................................................... 25

<uses-permission> ....................................................................................... 25

<permission> ............................................................................................... 25

<instrumentation> ....................................................................................... 25

<application> ............................................................................................... 25

<meta-data> ................................................................................................ 27

<receiver> .................................................................................................... 27

<service> ...................................................................................................... 27

<provider> ................................................................................................... 28

Resources and the magic R.java ................................................ 29

Resources ..................................................................................... 29

List of resources ........................................................................................... 29

Using resources in code ............................................................................... 30

Referencing Resources ................................................................................ 31

Alternate Resources & Localization ................................................ 32

The magic R.java ........................................................................... 33

Hello World – The Android way. ................................................ 34

Installing the Android SDK ............................................................. 35

The Android Development Tools (ADT) ....................................................... 35

Installation done, let’s do some code ............................................. 37

Creating a new Android Project .................................................................. 37

Running your first application ..................................................................... 43

UIs the Java way ........................................................................... 45

System.out.println(…) ? ................................................................. 46

The LogCat ................................................................................................... 46

Using Intents ............................................................................ 49

Starting (Sub)Activities .................................................................. 49

Finding XML-defined Views in Java-Code .................................................... 52

Handling Clicks to Views .............................................................................. 53

Returning values from SubActivities ........................................................... 56

Passing Data to (Sub)Activities ...................................................... 58

Important Layouts and ViewGroups .......................................... 60

The RelativeLayout ........................................................................ 60

Bibliography ............................................................................. 61

Lost chapters ............................................................................ 62

The communities .......................................................................... 62

wink.gif

nuts.gif

explicit_code.png

Foreword / How to read this doc

前言/如何阅读本文档

This document was written for developers who have worked with Java.

before and want to start developing for the Android Platform. I tried to

make this as much “hands on” as possible, placing example codes

everywhere it fit. Also I tried to insert as many picture as possible,

because they liven up the learning process and relax the reader’s eyes.

这个文档是为那些做过java开发并且向继续在Android平台开发的开发者而写的。我把示例代码放在每一个适合的地方,便于让开发更加容易上手。此外,我也试着插入尽可能多的图片,因为图片能够使学习过程更加生动并且让读者能轻松的阅读。

But unfortunately coding is not everything; one has to learn about

some basic facts of the Android Platform to fully understand. That is

what is described on the first ~XXX pages. It is not necessary to read all

those describing pages, but it is preferable. You could decide to treat it as

a kind of reference. What you would read there is also explained when it

occurs during the “hands on”-process. So you could directly start at Hello

World – The Android Way.

但不幸的编码不是万能的,人们必须了解在Android平台的一些基本事实,以便于充分理解。这就是在最开始的部分要描述的内容。虽然不必要全部阅读这些描述部分,但是最好还是读一下。你可以决定将其视为一种参考,你在这些部分读到的内容也会在之后实际动手的过程中有相关解释。因此,你可以直接开始你的Android旅程的第一个程序Hello World

All codes you see in this document (the whole workspace) will be

available on:

所有代码你在这个文档中看到的(整个工作区)将会在下面的网站中提供。

http://andbook.anddev.org/sources/

Have fun reading…

接下来,请尽情地在阅读中寻找你的快乐吧

Introduction

简介

The Open Handset Alliance (1) released the Google Android SDK on

November 12th, 2007, having announced it about a week before. The

impact was unbelievable, almost every IT/programming-related news-

page dumped a news-post about the SDK release – the Google Groups (2)

was overwhelmed with over 2000 Messages within the first two Days.

The idea of the Android Platform was and still is amazing and is of course

attracting more and more programmers every day. Especially the open

architecture based on Intents and the possibility to replace even the

Home-application grant a really large amount of flexibility to the whole

platform.

一个星期前的报道宣称,开放手机联盟在20071112日发布了Google Android SDK。其影响真是令人难以置信,几乎所有IT和编程有关的页面都开辟专栏报道有关的SDK发布信息,而Google的工作小组更是在前两天被超过2000条的邮件弄的不堪重负。Android平台的想法过去并且现在仍然是令人惊异的并且每天都吸引着越来越多的程序员的加入。尤其是基于意图和甚至可能替代桌面应用的开发架构保证了真正的整个平台的灵活性。

Android – Imagination is the limit”1

Android-想象的极限。

1 Nicolas Gramlich – anddev.org Site-Admin

尼古拉格拉姆利克 - anddev.org网站管理员

What is Android – a GPhone?

什么是Android 是一个google的手机GPhone?

The weeks and months before Google released the Android SDK there

had been a lot of rumors about a so called GPhone. It was said to be a

mobile device manufactured by Google providing free communication by

showing context-sensitive advertisements to the user on the device

itself.

几个星期和几个月前谷歌发布了Android SDK一直有很多传言这只是所谓的Gphone。据说这是一个由google生产的移动设备,它通过在设备上显示上下文敏感的广告给用户提供免费的通信。

Picture 1 Render of a potential GPhone

But on November 5th 2007 Andy Rubin2 announced:

但在2007115日安迪Rubin2宣布:

[The] Android [Platform] – is more significant and ambitious than a single

phone.”

该机器人平台 比单一手机更有意义并且更有雄心。

Google within the Open Handset Alliance (OHA) delivers a complete set

of software for mobile devices: an operating system, middleware and key

mobile applications. What was released a week later was not a final

product, but a “First Look SDK” what many did not realize. Major news

sites grabbed the discomforts of some developers who said that Android

is full of bugs and heavily lacks of documentation. But the majority says

that Android is not buggier than any other software at this stage.

谷歌开放手机联盟提供了一套完整用于移动设备的软件:操作系统,中间件和关键
移动应用。发布一周之后仍然不是一个最终产品,但是,在“第一印象的SDK”里,很多人都没有意识到。主要的新闻网站抓住一些开发人员对 Android 充满了错误并且严重缺乏的文档的不适。但多数不说,Android是在现阶段比任何其他软件bug更少。

2 Andy Rubin – Google Director of Mobile Platforms

安迪鲁宾 - 谷歌移动平台总监

Android from above

Let’s take a look at what the OHA emphasizes on its Android Platform:

从上面的android介绍,让我们再看一看,开放手机联盟强调的Android平台的外观。

Openness

开放性

Android was built from the ground-up to enable developers to create

compelling mobile applications that take full advantage of all a

handset has to offer. It is built to be truly open. For example, an

application could call upon any of the phone's core functionality such

as making calls, sending text messages, or using the camera, allowing

developers to create richer and more cohesive experiences for users.”

This is true, as a developer you can do everything, from sending short

messages with just 2 lines of code, up to replacing even the HOME-

Screen of your device. One could easily create a fully customized

operating system within weeks, providing no more of Google’s default

application to the user.

Android从建立就是为了让开发人员能够充分利用移动设备可以提供的功能实现一些应用。它将是一个真正开放的平台。例如,应用程序可以调用手机的核心功能,如任何打电话,发送短信,或使用相机时,允许开发者创建更丰富,更具亲和力的用户体验应用。这是真的,作为一个开发者你可以做一切事情。发送一行短消息仅仅只需要2行代码,甚至正取代设备桌面屏幕应用。人们可以在几周内很容易地创建一个完全个性化定制操作系统,没有谷歌提供的默认更多应用给用户。

Android is built on the open Linux Kernel. Furthermore, it utilizes a

custom virtual machine that has been designed to optimize memory

and hardware resources in a mobile environment. Android will be

open source; it can be liberally extended to incorporate new cutting

edge technologies as they emerge. The platform will continue to

evolve as the developer community works together to build innovative

mobile applications.”

Android是建立在开放的Linux内核。此外,它采用一自定义虚拟机的设计以优化移动环境的内存和硬件资源。Android将会是开源的,它可以随着先进技术的出现进行自由扩展。该平台将会继续演变为一个一起工作的开发者社区,来创立更多新的移动应用。

Here Google is talking of the so called Dalvik virtual machine (DalvikVM),

which is a register based virtual machine, designed and written by Dan

Bornstein and some other Google engineers, to be an important part of

the Android platform. In the words “register based” we find the first

difference to normal Java virtual machines (JVM) which are stack based.

See the “Dalvik.equals(Java) == false”-chapter for more details on that

issue.

谷歌提出的是这里的所谓的Dalvik虚拟机(DalvikVM)是基于寄存器的虚拟机,它由丹伯恩斯坦和其他一些谷歌工程师设计并编码,是Android平台一个重要组成部分。在该平台基于寄存器的设计中,我们发现了它区别于java虚拟机的第一个不同点那就是java虚拟机是基于堆栈设计的。在文章的“Dalvik.equals(Java) == false”这章可以看到更加详细的信息。

All applications are created equal

所有应用都是平等的。

Android does not differentiate between the phone's core applications

and third-party applications. They can all be built to have equal access

to a phone's capabilities providing users with a broad spectrum of

applications and services. With devices built on the Android Platform,

users will be able to fully tailor the phone to their interests. They can

swap out the phone's home screen, the style of the dialer, or any of

the applications. They can even instruct their phones to use their

favorite photo viewing application to handle the viewing of all

photos.”

Android不会区分手机的核心应用和第三方应用程序。他们都可以有平等机会使用手机的功能来提供广泛的用户应用和服务。设备建立在Android的平台,用户将能够根据自己的喜好自由定制手机。他们可以掉了手机的主屏幕,该拨号器,或任何风格申请。他们甚至可以指导他们使用他们的手机
最喜欢的照片浏览应用程序来处理所有观看照片。”

Once again this is all true. Developers can 100% customize their Android-

Device. The Android System Communication is based on so called Intents,

which are more or less just a String (with some data attached) which

defines an action that needs to be handled. An example for this is:

android.provider.Telephony.SMS_RECEIVED”

再一次说道,这是真正的,开发人员可以100%定制自己Android装置。Android的系统通信时基于所谓的意图,意图或多或少只是一个字符串(有一些附加的数据),其中定义了一个动作,需要加以处理。一个很好的例子来说明就是:

android.provider.Telephony.SMS_RECEIVED

One can simply listen on that Intent by writing about 5 lines of

definitions. The system would then recognize that there is more than one

application that wants to handle that Intent and ask the user to choose

which one he or she would like to handle the Intent.

程序员可以通过5行定义就能监听这个意图。系统便会知道有超过一个应用程序需要处理的意图,并且要求用户选择一个应用程序来监听这个意图。

Breaking down application boundaries

打破应用程序之间的边界

Android breaks down the barriers to building new and innovative

applications. For example, a developer can combine information from

the web with data on an individual's mobile phone - such as the user's

contacts, calendar, or geographic location - to provide a more relevant

user experience. With Android, a developer could build an application

that enables users to view the location of their friends and be alerted

when they are in the vicinity giving them a chance to connect.”

Android打破了创立新的和创新应用的障碍。例如,一个开发人员可以把从网页上获取的信息与个人用户的移动电话,比如联系人信息,日历或者地理位置信息结合起来,带来更为全,面的用户体验。使用Android,一个开发者可以建立一个应用程序,让用户查看他们的朋友的位置,并且当他们在附近时进行提醒让他们有机会进行连接。

Fast & easy application development

快捷,方便的应用开发

Android provides access to a wide range of useful libraries and tools

that can be used to build rich applications. For example, Android

enables developers to obtain the location of the device, and allows

devices to communicate with one another enabling rich peer-to-peer

social applications. In addition, Android includes a full set of tools that

have been built from the ground up alongside the platform providing

developers with high productivity and deep insight into their

applications.”

Android 提供了丰富的有用的库和工具来建立丰富多彩的应用。

比如说,Android允许开发者能够获得设备的位置,并允许设备互相沟通以实现点对点的社会应用。此外,Android包括了一个完整的从底层构建的平台的工具集合,为开发者在他们的应用程序中提供更高的生产力和更深的眼界。

Since the Web 2.0 revolution, making content rich applications within

minutes is no more illusion. Android has brought developing to unknown

speeds. Let me provide an example:

Someday I stumbled over the Buzzword ‘DrivingDirections’ within the

Android-Documentation.

由于Web2.0的革命,在短时间内构建内容丰富的应用程序不再是幻想。Android给开发带来了无止尽的速度。有一天,我偶然在Android的文档里发现了一个时髦的术语'DrivingDirections

Thought – done.

Picture 2 Google DrivingDirections implementation in Android

The development process of the application in the picture above took

about 1. hours! (Including the simple user interface and all images you

see). Could one create such a sophisticated application on any other

mobile-platform? – No.

该图中的应用程序开发过程需约1.5个小时(包括简单的用户界面和所有的你看到的图片)。

你能够在其他的移动平台上在这么短的时间内建立一个如此复杂的程序么?不可能吧。


Additionally this application could be enriched with the current GPS-

position of the device within a handful of code-lines.

此外,这个应用可以用当前设备的GPS来丰富,只需要简单地手写几行代码。

Google emphasizes Androids power of providing location-based-services.

Google Maps are so neat within Android as if it was just developed for

Android. One can integrate a fully zoom and drag enabled map by adding

just 3(!) characters in the Java-Code of the Android-Default-Application

and 3 lines of XML-Code.

Google 强调Android基于位置服务的权限。Google地图在Android里应用如此容易仿佛它就是为了Android而开发的。人们可以完全集成地图的变焦和拖动只用在默认应用里添加3java代码和3xml代码。

Other nice features that are easy to use with Android are Animations and

media-playback. Since version m5, the Android SDK contains functions

for straight and reverse GeoCoding and in addition to mp3, playback of:

ogg-Vorbis, MIDI and a bunch of other formats.

其他一些用Android容易实现的简单功能有动画和媒体播放,从M5版本开始,Android SDK包含了为正反地理编码和支持mp3播放 ogg-Vorbis,MIDI以及其他一系列播放格式。

The first weeks

最初的几周

Unfortunately the developers had to deal with a not fully implemented

preview-SDK (initially released build: ‘m3-rc20’), where even some key-

parts of the SDK were poorly documented. The lack of documentation

leaded to an explosion of the Android-Developer-Group within the

Google-Groups.

不幸的是,在最初的几周,开发者不得不面对没有完全实施的SDK前置版本(最初的释放版’m3-rc20’,在里面甚至一些SDK的关键部分描述的仍然不够广泛。缺少文档导致了Google团队里的Google开发者团队的爆炸。

Sooner or later one had to respect the statement from

Google:

If it is not documented it is not meant to work yet.“

Many developers did not realize that fact that the first SDK released were

first-looks or developer-previews, where changes in the API had to be

awaited.

迟早,程序员必须面对Google造成的这一情景,如果没有充分的文档,是不是就意味着不要工作呢。

许多开发者还没有意识到这样的一个事实,第一个发布的sdk只是一个第一概貌或者说只是一个开发者的前序预览,还有大量API的改变需要我们等待。

Another annoying bug was the choppy emulator-sound, which was said

fixed with the release of build ‘m3-rc37a’ about 4 weeks later, but still

happened on some setups up to m5.

另一个恼人的错误是波涛汹涌的仿真器声,据说会在‘m3-rc37a’版本中也就是4周之后修正,但是在m5安装以后这种错误依然存在。

Dalvik.equals(Java) == false

Dalvikjava不相等

Why “Dalvik”? – The Dalvik virtual machine was named by Bornstein after

the fishing village of Dalvík in Eyjafj.reur (Iceland), where some of his

ancestors lived.

为什么叫Dalvik- Dalvik虚拟机是由Bornstein根据冰岛的小渔村Dalvik村命名的,他的祖先曾居住在那里。

As you may have heard of, Dalvik is the name of Android's virtual

machine. It is an interpreter-only virtual machine that executes files in

the Dalvik Executable (*.dex) format, a format that is optimized for

efficient storage and memory-mappable execution. The virtual machine

is register-based, and it can run classes compiled by a Java language

compiler that have been transformed into its native format using the

included "dx" tool. The VM runs on top of a Linux 2.6 kernel, which it

relies on for underlying functionality (such as threading and low level

memory management). The DalvikVM was also optimized to be running

in multiple instances with a very low memory-footprint. Several VMs

protect ones application from being dragged down by another crashed

Application.

正如你已经听说过,DalvikAndroid的虚拟机。它是一个解释执行的虚拟机,它执行Dalvik可执行文件(*.dex)格式,一个对有效存储和内存填涂执行优化的格式。这个虚拟机是基于寄存器的,并且它可以执行由java语言编译的类。编译器包含“dx”工具已经被转化为本地格式。虚拟机在Linux 2.6版本内核上运行。它依靠一些基本的功能(比如线程和低水平内存管理)。这个Dalvik虚拟机还优化运行多个实例仅仅使用一个非常低的内存足迹。几个虚拟机保护一些应用防止他们被其他突然崩溃的应用所毁坏。

Differences to a normal JavaVM

与一个正常的java虚拟机之间的区别。

JavaVM’s one can find on almost any desktop computer nowadays are

Stack-based Virtual Machines (VM).The DalvikVM on the other hand is

register based, because on mobile-processors are optimized for register-

based execution. Also of register-based VMs allow faster execution times

at the expense of programs which are larger after compilation.

Java虚拟机可以在几乎任何桌面电脑现在是
基于堆栈的虚拟机(VM)中找到。在另一方面,Dalvik虚拟机基于寄存器的,因为在移动处理器上,采用继续寄存器的执行更加优化。同样,基于移动处理器虚拟机允许更快的执行时间,但是在编译之后程序也会更大。


The Android Code Challenge

Android的编程挑战

The Android Code Challenge (ADC) is an idea of Google to encourage the

community to build cool applications for the Android Platform by

rewarding the 50 most promising applications submitted.

Android编程挑战是GoogleAndroid平台设立的为了鼓励开发人员一起来创新更酷平台的一个想法。

Picture 3 Android Developer Challenge Logo

Of course the Android Developers Challenge, with its overall 10 Million

Dollars of prize money, was attracting even more software-developers to

create a bunch of really useful applications. On the other side many

voices said, that this was no good choice from Google, because it would

lead to less code-sharing, as many would fear sharing their ideas with a

community, during the first important months after the SDK release.

当然,Android开发者大赛,因为有整整1千万美元的奖励,所以它吸引了更多软件开发人员去开发一些真正有用的应用程序。在另一方面,也有人说,这是因为Google没有更好的选择,因为这将会导致更少的代码共享,因为很多人担心一个开发者社区在第一个重要的SDK发布之后会分享他们的思想。

There were two Challenges planned:

计划中比赛分为两个阶段:

. Android Developer Challenge I: Submissions up to April 14, 2008

. Android Developer Challenge II: This part will launch after the

first handsets built on the platform become available in the

second half of 2008.

第一阶段:2008314日之前,提交建议书。

第二阶段:在2008年下半年,需要提交能在平台上运行的应用。

In the Android Developer Challenge I, the 50 most promising entries

submitted by April 14 will each receive a $25,000 award to fund further

development. Those selected will then be eligible for even greater

recognition via ten $275,000 awards and ten $100,000 awards.

Applications submitted to the Challenge were supposed to be innovative

and demonstrate all the capabilities of the Android platform, like location

based services, media consumption, gaming and social networking, to

enrich mobile experience.

在第一阶段,50个最有希望的参赛方案将收到25000美元奖励资金作为进一步发展之用。这些被选中的作品将有可能获得更大的275000美元和10万美元的奖励。参加比赛的应用程序应该有创新性并且能够在Android平台上进行使用,比如基于未知的服务,媒体消费,游戏和社交,来获得丰富的移动体验。


Creating Android Applications

创建Android应用程序

In this chapter we will concentrate on the specialties in creating any

Android-Application.

在这章之中,我们将会集中在如何创建Android应用程序。

Anatomy of an Android Application

解剖Android应用

There are four building blocks to an Android application:

. Activity

. Intent Receiver

. Service

. Content Provider

Android应用有四个主要的构建块:

活动

意向收集机

服务

内容提供

Not every application needs to have all four, but your application will be

written with some combination of these.

不是每个应用程序都拥有以上四种模块,但是您的应用程序需要把其中的一些结合起来。

Once you have decided what components you need for your application,

you should list them in a file called AndroidManifest.xml. This is an

XML file where you declare the components of your application and what

their capabilities and requirements are. We will discuss soon, what the

AndroidManifest.xml is responsible for.

一旦决定您的应用程序需要哪些组件,您应该在一个名为 AndroidManifest.xml 的文件中对其进行列表声明。这是一个声明应用程序组件的功能和需求的XML文件。我们很快就会谈到,AndroidManifest.xml是做什么用的。

Activity

活动

Activities are the most common of the four Android building blocks. An

activity is usually a single screen in your application. Each activity is

implemented as a single class that extends the Activity base class. Your

class will display a user interface composed of Views and respond to

events.

活动4Android构造块中最常见的,一个活动通常就是在应用程序中的一个单独的界面。

每一个活动都是作为一个独立的类从活动的基类扩展实现。您的类将显示由视图组成用户界面并且响应事件。

Most applications consist of multiple screens. For example, a text

messaging application might have one screen that shows a list of

contacts to send messages to, a second screen to write the message to

the chosen contact, and other screens to review old messages or change

settings. Each of these screens would be implemented as an activity.

Moving to another screen is accomplished by a starting a new activity. In

some cases an Activity may return a value to the previous activity - for example an activity that lets the user pick a photo would return the chosen photo to the caller.

When a new screen opens, the previous screen is paused and put onto a

history stack. The user can navigate backward through previously opened

screens in the history. Screens can also choose to be removed from the

history stack when it would be inappropriate for them to remain.

Android retains history stacks for each application launched from the

home screen.

大多数应用程序由多个页面组成。例如一个文本消息的应用程序不要有一个页面显示一列联系人来发送消息,第二个页面来写消息给选中的联系人,还有一个页面来查看旧的消息或者更改设置。每一个这样的页面都被新开的一个活动来完成。在一些情况下,一个活动可能返回一个值给前一个活动。比如说一个活动让用户选择一个照片,将会返回选定的照片给调用者。当一个新的页面打开时,前一页被暂停并且放入一个历史堆栈里。用户可以向后浏览历史记录中打开过的页面。当页面不适合继续留在堆栈中时,也可以从历史栈中删除。

Android保留从主屏幕起启动的所有程序在历史栈中。

Intent and Intent Filters

IntentIntent筛选器

Android uses a special class called Intent to move from screen to

screen. Intent describe what an application wants done. The two most

important parts of the intent data structure are the action and the data

to act upon. Typical values for action are MAIN (the front door of the

application), VIEW, PICK, EDIT, etc. The data is expressed as a Uniform

Resource Indicator (URI). For example, to view a website in the browser,

you would create an Intent with the VIEW action and the data set to a

Website-URI.

Android用一个特殊类从一个页面跳转到另外一个页面。Intent描述了一个应用程序想要做的事。Intent数据结构最重要部分是动作和接下来要用到的数据。典型的动作值就是MAIN(应用程序入口函数),VIEW,PICK,EDIT等等。这些数据用统一资源标识符URI来表示。

new Intent(android.content.Intent.VIEW_ACTION,

ContentURI.create("http://anddev.org"));

There is a related class called an IntentFilter. While an intent is

effectively a request to do something, an intent filter is a description of

what intents an activity (or intent receiver, see below) is capable of

handling. An activity that is able to display contact information for a

person would publish an IntentFilter that said that it knows how to

handle the action VIEW when applied to data representing a person.

Activities publish their IntentFilters in the AndroidManifest.xml

file.

有一个相关的类叫做IntentFilter。当一个Intent发出一个请求来做某事时,一个

当一个Intent发出某种请求时,一个IntentFilter是描述什么是这个活动需要处理的意图。

一个能够对一个人显示联系人信息的活动会发布一个IntentFilter表示它知道如何处理当代表一个人的操作数据的VIEW的这个动作。活动把他们的IntentFilters声明在AndroidManifest.xml 文件中。

Navigating from screen to screen is accomplished by resolving intents. To

navigate forward, an activity calls startActivity(myIntent). The

system then looks at the intent filters for all installed applications and

picks the activity whose intent filters best matches myIntent. The new

activity is informed of the intent, which causes it to be launched. The

process of resolving intents happens at run time when startActivity is

called, which offers two key benefits:

从页面到页面的导航通过载入intents实现。为了载入下一个页面,一个活动调用函数startActivity(myIntent)。系统将会从相应的intent filters中找出安装了的应用并且选在这些intent filters最适合自己Intent的应用。这个新的活动在这个intent中声明并启动。解析intents的过程发生在startActivity调用时,提供了两个比较方便的应用:

. Activities can reuse functionality from other components simply

by making a request in the form of an Intent

. Activities can be replaced at any time by a new Activity with an

equivalent IntentFilter

活动可以重复使用其他组件的功能,仅需要通过请求其中的一个目的形式。

活动还可以在任何时候与一个等效的IntentFilter进行替换。

Intent Receiver

Intent接收器

You can use an IntentReceiver when you want code in your

application to execute in reaction to an external event, for example,

when the phone rings, or when the data network is available, or when it's

midnight. Intent receivers do not display a UI, although they may display

Notifications to alert the user if something interesting has

happened.

当你想要在你的应用程序中编码来对一个外部事件做出响应,可以用一个IntentReceiver 。比如,当电话铃响起时或者当数据网络可以使用时,或者当半夜来临时。虽然Intent receivers可以能显示通知提醒用户如果有一些用户感兴趣的事情发生了,但是它们不会显示一个用户界面。

Intent receivers are also registered in

AndroidManifest.xml, but you can also register them from code

using Context.registerReceiver(). Your application does not

have to be running for its intent receivers to be called; the system will

start your application, if necessary, when an intent receiver is triggered.

Applications can also send their own intent broadcasts to others with

Context.broadcastIntent().

Intent receivers也会在AndroidManifest.xml中进行声明,但是您也可以在代码中声明,调用语句Context.registerReceiver()。您的应用程序并不是必须运行所谓的intent receivers;系统将会启动您的应用程序,如果有必要的话,一个intent receiver会被触发。应用程序也可以发送给其他intent一个广播用Context.broadcastIntent()

Service

服务

A Service is code that is long-lived and runs without a UI. A good

example of this is a media player playing songs from a play list. In a

media player application, there would probably be one or more activities

that allow the user to choose songs and start playing them. However, the

music playback itself should not be handled by an activity because the

user will expect the music to keep playing even after navigating to a new

screen.

服务时一种没有用户界面的长期后台运行的代码。一个服务的好的例子就是一个播放器通过一个播放列表播放歌曲。在一个媒体播放应用中,可能会有一个或者多个活动,让用户可以选择歌曲并且开始播放它们。但是,音乐播放本身不应该由活动处理因为用户可能在进入到一个新的页面后希望音乐继续运行。

In this case, the media player activity could start a service using

Context.startService() to run in the background to keep the

music going.

在这种情况下,媒体播放器活动可以开启一个服务调用Context.startService()在后台保证音乐的运行。

The system will then keep the music playback service

running until it has finished. (You can learn more about the priority given

to services in the system by reading Life Cycle of an Android Application.)

Note that you can connect to a service (and start it if it's not already

running) with the Context.bindService() method. When

connected to a service, you can communicate with it through an

interface exposed by the service. For the music service, this might allow

you to pause, rewind, etc.

系统会在后台保持这个音乐服务直到它播放完成。(您可以通过阅读Android应用程序的生命周期学习更多在系统中关于授予服务权限的知识)记住你可以连接到服务(并且启动它如果它没有运行)通过使用Context.bindService()方法。当连接到一个服务时,你可以同服务通过一个服务的接口进行通信。对于这个音乐服务来说,这可能可以让你暂停或者重播

Content Provider

Applications can store their data in files, a SQLite database, preferences

or any other mechanism that makes sense. A content provider, however,

is useful if you want your application's data to be shared with other

applications. A content provider is a class that implements a standard set

of methods to let other applications store and retrieve the type of data

that is handled by that content provider.

应用程序可以把他们的数据保存在文件,SQLite数据库,首选项或者其他有意义的机制里。如果您想要您的应用程序数据与其他应用程序共享,那么一个content provider无疑是有用的。一个content provider就是一个类,实现一组标准的方法使其他应用程序通过自己的content provider存储和检索自己的数据

Android User Interfaces

Android 用户界面

User Interfaces (UI) in Android can be built within two ways, by defining

XML-Code or by writing Java-Code. Defining the GUI structure in XML is

highly preferable, because as one knows from the Model-Viewer-Control

principle that the UI should always be separated from the program-logic.

Additionally adapting a program from one screen-resolution to another is

a lot easier.

Android的用户界面能够用两种方法构建,通过xml代码或者java代码。定义使用xml定义图形界面结构是优先考虑的,因为一个直到UI始终分为模型-界面-控制原则的程序员认为,用户界面应该与程序的逻辑结构分离。此外,程序从一个页面跳转到另外个页面适应分辨率变得更加容易。

Defining a UI in XML is very similar to creating a common HTML-

document, where you have i.e. such a simple file:

定义一个XML的用户界面跟定义一个普通的HTML文件类似,就像下面这个简单的文件一样:

<html>

<head>

<title>Page Title</title>

</head>

<body>

The content of the body element.

</body>

</html>

Just the same as in Android’s XML-Layouts. Everything is well structured

and can be expressed by tree-structures:

可以用树结构显示。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World"/>

</LinearLayout>

Hierarchy of Screen Elements

屏幕元素的层次结构

The basic functional unit of an Android application is the activity-an

object of the class android.app.Activity. An activity can do many

things, but by itself it does not have a presence on the screen. To give

your activity a screen presence and design its UI, you work with views

and viewgroups - basic units of user interface expression on the Android

platform.

Android应用程序的基本功能单位是一个活动对象的类android.app.Activity

一个活动可以做很多事情,但是本身并无一个出现在屏幕上。要给您的活动一个屏幕展示并且设计它的用户界面,您需要使用用视图或者视图组-Android平台上基本的用户界面表达联合类型。

Views

视图

A view is an object extending the base class android.view.View. It's

a data structure whose properties store the layout and content for a

specific rectangular area of the screen. A View object handles measuring,

its layout, drawing, focus changes, scrolling, and key/gestures for the

screen area it represents.

视图是从基类android.view.View扩展出来的一个对象。其数据结构的属性里存储了在屏幕的一个特定举行区域的内容和风格。View对象处理屏幕区域上测量,去布局,绘图,焦点的更改,滚轮,按键手势等行为。

The View class serves as a base class for all widgets - a set of fully

implemented subclasses that draw interactive screen elements. Widgets

handle their own measuring and drawing, so you can use them to build

your UI more quickly. The list of widgets available includes i.e. TextView,

EditText, Button, RadioButton, Checkbox, ScrollView, …

视图类作为所有widgets元素的基类----一套完全实现子类并且绘制交互式屏幕元素。

widgets处理自己的测量和绘图,因此您可以使用它们更快地构建您的用户界面。可用的widgets控件包括TextView, EditText, Button, RadioButton, Checkbox, ScrollView,

Viewgroups

A viewgroup is an object of class android.view.Viewgroup. As its

name indicates, a viewgroup is a special type of view object whose

function is to contain and manage a subordinate set of views and other

viewgroups, Viewgroups let you add structure to your UI and build up

complex screen elements that can be addressed as a single entity.

The Viewgroup class serves as a base class for layouts - a set of fully

implemented subclasses that provide common types of screen layout.

The layouts give you a way to build a structure for a set of views.

viewgroup是从基类android.view. Viewgroup扩展出来的一个对象。正如其名字我们可以猜测,一个viewgroup就是一个特殊类型的view对象,功能就是包含和管理从属的viewsviewgroupsViewgroups可以将结构添加到您的用户界面,并建立可作为单个实体的复杂的屏幕元素。Viewgroup就用作是一个基类,用于布局-完全实现一般的屏幕布局的子类。这个布局给了你一种方法来建立一个view的结构。

A Tree-Structured UI

On the Android platform, you define an Activity's UI using a tree of view

and viewgroup nodes, as shown in the diagram below. The tree can be as

simple or complex as you need to make it, and you can build it up using

Android's set of predefined widgets and layouts or custom view types

that you create yourself.

Android平台上,您定义一个活动的用户界面用棵树的view viewgroup 节点,来在下面显示图标。树可以是简单或者复杂都由您自己决定,您可以用Android的预定义的widgets和布局或者您自己创建的自定义视图类来建立它。

Picture 4 Android UI - Tree structure

To attach the tree to the screen for rendering, your Activity calls its

setContentView() method and passes a reference to the root node

object. Once the Android system has the reference to the root node

object, it can work directly with the node to invalidate, measure, and

draw the tree. When your Activity becomes active and receives focus, the

system notifies your activity and requests the root node to measure and

draw the tree. The root node then requests that its child nodes draw

themselves - in turn, each viewgroup node in the tree is responsible for

drawing its direct children.

要在屏幕上呈现用户界面,您的活动需要调用setContentView()并传递一个参数到树根节点。

一旦Android系统找到了根节点,它就可以直接根据节点来测量并且绘制界面。当激活您的活动并接收焦点消息,系统将会通知您的活动并请求测量和绘制树的根节点。反过来,树中每一个树中的viewgroup节点又负责画出它的直接孩子。

As mentioned previously, each view group has the responsibility of

measuring its available space, laying out its children, and calling draw()

on each child to let it render itself. The children may request a size and

location in the parent, but the parent object has the final decision on

where how big each child can be.

正如前面提到的,每个view group将有责任测量其可用空间,画出其子级布局,对每一个子布局调用draw()。子布局可以在父布局里请求一个空间和位置,但是父对象有最终决定权决定每个孩子有多大。

Comparing Android UI Elements to Swing UI Elements

比较Android UI元素和Swing UI元素

As some developers who are reading this have probably coded UIs with

Swing before here are some similarities between Android and Swing.

因为一些开发者在读这篇文章的同时也与之前用过swingUI进行编程。这里有一些在AndroidSwing之间的相似之处。

. Activities in Android refers almost to a (J)Frame in Swing.

. Views in Android refers to (J)Components in Swing.

. TextViews in Android refers to a (J)Labels in Swing.

. EditTexts in Android refers to a (J)TextFields in Swing.

. Buttons in Android refers to a (J)Buttons in Swing.

Android中提到的Activity几乎相当于Swing里的Frame

Android中的Views相当Swing里的Components

Android中的TextViews相当于Swing里的Labels

Android中的EditTexts相当于Swing里的TextFields

Setting listeners to a View is nearly the same in Android than in Swing.

View里设置监听和Swing里的差不多

// Android

myView.setOnClickListener(new OnClickListener(){ ...

// Swing

myButton.addActionListener(new ActionListener() {...

The AndroidManifest.xml

The AndroidManifest.xml is a required file for every Android

application. It is located in the root folder of the application, and

describes global values for your package, including the application

components (activities, services, etc) that the package exposes to the

outer world’, what kind of data each of our Activities and co. can handle,

and how they can be launched.

AndroidManifest.xml是一个对于每一个Android 应用都需要的。它位于应用的根目录,并且说明了为你的软件的全球的一个值。包括应用程序组件(活动,服务等),包公开向外部世界包括了每一个活动处理什么数据并且他们应该怎么运行。

An important thing to mention of this file are its so called IntentFilters.

These filters describe where and when that activity can be started. When

an activity (or the operating system) wants to perform an action such as

open a Web page or open a contact picker screen, it creates an Intent

object.

所谓的IntentFilters是这个文件的一个重要的部分。这些filters描述了何时何地可以启动这一活动。当活动(或操作系统)想要执行一个操作比如打开一个web网页或者打开一个联系人选择屏幕,它就会创建一个intent对象。

This Intent-object can hold several information describing what

you want to do, what data is needed to accomplish it and other bits of

information. Android compares the information in an Intent object with

the intent filter exposed by every application and finds the activity most

appropriate to handle the data or action specified by the caller. If there it

more than one application capable of handling that Intent, the user gets

asked, which app he would prefer handling it.

此目的对象可以保存几个要做的信息描述,需要哪些数据完成它和其他一些信息。Android intent中的信息对象与每一个应用程序的intent filter进行比较并且找出最适合处理这个数据的程序,或者调用者定义的特殊动作来处理。如果有超过一个应用程序恩能够处理这个Intent,用户将会获取到一个询问,让他选择一个应用程序来处理。

Besides declaring your application's Activities, Content Providers,

Services, and Intent Receivers, you can also specify permissions in

AndroidManifest.xml.

除了声明您的应用程序的Activities, Content Providers, Services, Intent Receivers,你也可以在AndroidManifest.xml定义权限。

app_added.png

General

A very simple AndroidManifest.xml looks like this:

一个非常简单的AndroidManifest.xml就像如下所述

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="org.anddev.android.hello_android">

<application android:icon="@drawable/icon">

<activity android:name=".Hello_Android"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

</manifest>

. Almost every AndroidManifest.xml (as well as many other

Android XML files) will include the namespace declaration

几乎每个AndroidManifest.xml都将会包括命名空间定义

(xmlns:android=http://schemas.android.com/apk/res/android)

in its first element. This makes a variety of standard Android

attributes available in the file, which will be used to supply most

of the data for elements in that file.

(xmlns:android=http://schemas.android.com/apk/res/android)

在它的第一个元素里。这定义了一系列在这个文件里可以使用的标准的Android属性,并且在这个文件中可以补充一些数据元素。

. Almost every manifest includes a single <application> tag,

which itself contains several tags describing Applications,

IntentReceivers, etc… that are available in this application.

. If you want to make an Activity launchable directly through the

user, you will need to make it support the MAIN action and

LAUNCHER category, what result as shown here:

几乎每个清单包含一个单一的 <application>标记,而其本身包含几个关键词描述 IntentReceivers,等可在的应用</application> 的此应用程序中,这个程序中可用的IntentReceivers等等。

如果你想让一个应用可以直接通过用户执行,你需要让它支持MAIN动作和LAUNCHER 类别,这将会有如下的结果:

Picture 5 Directly launchable Activity

What follows is a detailed list of the structure of an

AndroidManifest file, describing all available <tags>, with an

Example for each:

以下是一个AndroidManifest文件的详细的列表结构,描述了所有的可用的标签,每一个都由一个例子。

<manifest>

This is the root node of each AndroisManifest.xml. It contains the

package-attribute, which points to any package in out Activity. Other

Activities-path will base relative to its value.

这是每一个AndroisManifest.xml的根节点。它包含了报属性,任何包指向我们活动的点。其他活动路径以及基于它的值。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="org.anddev.android.smstretcher">

<uses-permission>

Describes a security permission, which your package must be

granted in order for it to operate correctly (i.e. when you want to send

SMS or use the Phone-Contacts). The permissions get granted by the user

during installation of your application. Quantity: 0+

描述您的软件包必须被授予的权限以保证它能正常运行(比如当您要发送短信或者使用联系人电话时)。这个权限由用户在安装应用的时候获取

<uses-permission android:name=" android.permission.RECEIVE_SMS"/>

<permission>

Declares a security permission that can be used to restrict which

applications can access components or features in your (or another)

package. Quantity: 0+

声明用于限制哪些应用程序可以访问您的组件或您的软件包中的功能的安全权限。

<instrumentation>

Declares the code of an instrumentation component that is

available to test the functionality of this or another package. See

Instrumentation for more details. Quantity: 0+

声明一个检测组件,这个组件可用于测试这个或另一个包的功能的代码。有关更多的详细信息请参见Instrumentation

<application>

Root element containing declarations of the application-level

components contained in the package. This element can also include

global and/or default attributes for the application, such as a label, icon,

theme, required permission, etc. Quantity: 0 or 1.

跟元素包含了一个包里面应用程序组件级别的声明。此元素还可以包含全局和应用程序的默认属性,比如一个标签,图标,主题以及默认属性所需要的权限。

<application android:icon="@drawable/icon">

exclamation.gif

You can place 0+of each of the following children:

<activity>

An Activity is the primary thing for an application to

interact with the user. The initial screen the user sees when

launching an application is an activity, and most other screens

they use will be implemented as separate activities declared with

additional activity tags.

活动是一个成语与用户进行交流的主要工具。当启动一个程序让用户看到初始化界面的是一个活动,并且大多数其他他们用到的作为单独活动的界面将会并使用其他活动的标签。

<activity android:name=".Welcome" android:label="@string/app_name">

Note: Every Activity must have an <activity> tag in the

manifest whether it is exposed to the world or intended for use

only within its own package. If an Activity has no matching tag

in the manifest, you won't be able to launch it.

Optionally, to support late runtime lookup, you can

include 1+ <intent-filter> elements to describe the actions the

activity supports.

每个活动不管它是向全世界发布的还是只在自己包中使用的都必须在manifest文件中有一个<activity>标签

<intent-filter>

Declares what kind of Intents a component

supports. In addition to the various kinds of values that

can be specified under this element, attributes can be

given here to supply a unique label, icon, and other

information for the action being described.

声明一个组件支持的Intents种类。为了扩展这个元素里的各种值和属性可以提供一个单独的标签图标和其他描述的动作信息。

<intent-filter>

<action>

An action-type that the component

supports. Example:

<action android:name="android.intent.action.MAIN" />

<category>

A category-type that the component

supports. Example:

<category android:name="android.intent.category.LAUNCHER" />

<data>

An MIME type, URI scheme, URI

authority, or URI path that the component

supports.

You can also associate 1+ pieces of meta-

data with your activity:

一个MIME 类型URI 方案,URI 机构或组件支持的 URI 路径。

<meta-data>

Adds a new piece of meta data to the activity,

which clients can retrieve through

ComponentInfo.metaData.

<receiver>

An IntentReceiver allows an application to be told

about changes to data or actions that happen, even if it is not

currently running. As with the activity tag, you can optionally

include 1+ <intent-filter> elements that the receiver

supports or <meta-data> values, just all the same as with

<activity>.

一个 IntentReceiver 允许讲数据或执行,操作的更改,即使它当前没有运行。

与该活动标记一样,您可以有多个<intent-filter>元素并且这个receiver支持<meta-data>值跟<activity>标签一样

<receiver android:name=".SMSReceiver">

<service>

A Service is a component that can run in the background

for an arbitrary amount of time. As with the activity tag, you can

optionally include one or more <intent-filter> elements that the

service supports or <meta-data> values; see the activity's

<intent-filter> and <meta-data> descriptions for more

information.

一个服务是一个能在后门运行任意长时间的组件。与该活动的标记一样还可以包含一个或者多个<intent-filter>元素,该服务支持<meta-data>值;请参阅活动的<intent-filter><meta-data>描述以获得更多信息。

<provider>

A ContentProvider is a component that manages

persistent data and publishes it for access by other applications.

You can also optionally attach one or more <meta-data> values,

as described in the activity's <meta-data> description.

Of course all <tags> have to be </closed> or closed

一个ContentProvider是一个持久性的数据管理组件,它为其他应用程序提供数据访问,可以在该活动的<meta-data>中声明它。当然所有的标签都得闭合。

<directly/>.

Resources and the magic R.java

资源和神奇的R.java文件

The resources of a project and the R.java are very close related.

一个项目的资源和R.java有着非常密切的联系。

Resources

资源

Resources are external files (non-code files) that are used by your code

and compiled into your application at build time. Android supports a

number of different kinds of resource files, including XML, PNG, and JPEG

files. The XML files have very different formats depending on what they

describe.

Resources are externalized from source code, and XML files are compiled

into a binary, fast loading format for efficiency reasons. Strings are

compressed into a more efficient storage form.

资源是外部文件(非代码文件)

List of resources

资源列表

Resource-types and where to place them:

资源的种类以及放置它们的地方

. layout-files . “/res/layout/”

. images . “/res/drawable/”

. animations . “/res/anim/”

. styles, strings and arrays . “/res/values/”

o Names do not have to be exactly like:

o ‘arrays.xml’ to define arrays

o ‘colors.xml’ to define colors

. #RGB, #ARGB, #RRGGBB, #AARRGGBB

o ‘dimens.xml’ to define dimensions

o ‘strings.xml’ to define strings

o ‘styles.xml’ to define style objects

. raw files like mp3s or videos . “/res/raw/”

Using resources in code

在代码中使用资源

Using resources in code is just a matter of knowing the full resource ID

and what type of object your resource has been compiled into. Here is

the syntax for referring to a resource:

在代码中使用的资源只是知道完整的资源ID和您的已经被编译的资源类型对象。

以下就是调用某个资源的语法。

R.resource_type.resource_name

or

android.R.resource_type.resource_name

Where resource_type is the R subclass that holds a specific type of

resource.resource_name is the name attribute for resources

defined in XML files, or the file name (without the extension) for

resources defined by other file types.

其中resource_type是包含特定类型的resource.resource_name的一个R子类

Each type of resource will be added

to a specific R subclass, depending on the type of resource it is.

每种类型的资源将被添加到一个特定 R 子类,这取决于它是的资源的类型。

Resources compiled by your own application can be referred to without a

package name (simply as R.resource_type.resource_name).

编译您自己的应用可以不需要包名(只需要用R.resource_type.resource_name

Android contains a number of standard resources, such as screen styles

and button backgrounds. To refer to these in code, you must qualify

them with android, as for example in:

Abdroid包含了许多标准的资源如屏幕样式和背景按钮。这些代码中引用,你必须用android限定它们,就像下面的例子中一样:

android.R.drawable.button_background.


Referencing Resources

A value supplied in an attribute (or resource) can also be a reference to

another resource. This is often used in layout files to supply strings (so

they can be localized) and images (which exist in another file), though a

reference can be any resource type including colors and integers.

For example, if we have color resources, we can write a layout file that

sets the text color size to be the value contained in one of those

resources:

属性(或者资源)中提供的值,也可以是另一资源的引用。虽然引用可以是任何资源类型,包括颜色和整数,但这通常用于布局文件来提供字符串(因此字符串可以本地化)和图片(在其他文件中的图片)。举个例子,比如我们有颜色的资源,我们可以写一个布局能够设置文本颜色的大小值作为包含在资源文件里的值。

<EditText

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:textColor="@color/opaque_red"

android:text="Hello, World!" />

Note here the use of the '@' prefix to introduce a resource reference --

the text following that is the name of a resource in the form of

@[package:]type/name. In this case we didn't need to specify the

package because we are referencing a resource in our own package. To

reference a system resource, you would need to write:

注意这里的@前缀,引入一个资源引用--之后的文字就是资源的名字,用这样的格式@[package:]type/name.在这种情况下,因为我们在自己包中引用的资源,所以我们不需要指定包。如果要引用系统资源,您需要写如下代码。

<EditText

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:textColor="@android:color/opaque_red"

android:text="Hello, World!" />

As another example, you should always use resource references when

supplying strings in a layout file so that they can be localized:

又如,您可以在布局文件里提供字符串时引用资源文件以保证其始终本地化:

<EditText

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:textColor="@android:color/opaque_red"

android:text="@string/hello_world" />


Alternate Resources & Localization

备用资源与本地化

Alternate Resources and Localization is a very useful issue you will love

Android for. Expect you would have to design a GUI that fits landscape

and portrait screen-orientation well at the same time – that is almost

impossible.

备用资源与本地化是一个非常有用的问题,您将会因此喜欢用Android来实现。如果您要想同时设计一个适合横向和纵向的图形界面,那几乎是不可能的。

You can supply different resources for your application according to the

UI language or hardware configuration of the device. Note that

Even though you can include different string, layout, and all other

resources, the SDK does not expose methods to let you specify which

alternate resource set to be used. Android detects the proper set for the

hardware and location, and loads them as appropriate.

您可以根据程序语言和设备的硬件配置为您的应用程序提供不同的资源。

请注意,尽管您可以包含不同的字符串,布局和所有其他的资源,SDK也不公开制定设置您的备用资源的方法。Android检测适合硬件和地区的资源集合,并且更加适合的加载它们。

Only the user can select alternate language settings using the settings panel on the device.

To include alternate resources, create parallel resource folders with

dash-separated qualifiers appended to the folder names, indicating the

configuration it applies to (language, screen orientation, dpi, resolution,

).

只有用户可以选择使用设备上的设备面板来设置语言。若要包括备用资源,创建用下划线分隔限定符号命名名称的并行资源文件夹,使用与设置指示各种配置(包括语言,屏幕方向,dpi分辨率)。

For example, here is a project differs between differs between English

and German value-resources (here only strings):

比如,以下就是一个在英文和德文文件下的资源摆放(这仅仅指示字符串)

MyApp/

res/

values-en/

strings.xml

values-de/

strings.xml

Android supports several types of qualifiers, with various values for each.

Append these to the end of the resource folder name, separated by

dashes. You can add multiple qualifiers to each folder name, but they

must appear in the order they are listed here. For example, a folder

containing drawable resources for a fully specified configuration would

look like:

Android 支持集中类型的定义限定符,每一种使用不同的资源。将这些添加到文件夹名结尾,用短划线分隔开。您可以将多个限定符添加到每个文件夹名,但是它们必须按它们列出的顺序出现。比如文件夹包含drawable资源的完全指定配置如下所示:

MyApp/

res/

drawable-en-rUS-port-92dpi-finger-keyshidden-12key-dpad-480x320/

More typically, you will only specify a few specific configuration options

that a resource is defined for. You may drop any of the values from the

complete list, as long as the remaining values are still in the same order:

一般,将仅指定一个资源定义的几个特殊的配置选项。您可以从完整列表中删除任何值,只要剩下的值依然是按顺序的:

MyApp/

res/

drawable-en-rUS-finger/

drawable-port/

drawable-port-160dpi/

drawable-qwerty/

Android will pick which of the various underlying resource files fits best

during runtime, depending on the current device-configuration.

Android将会在运行时选取其中的各种基础资源文件,具体取决于当前最适合的设备配置

The magic R.java

神奇的R.java

A project's R.java is an auto-generated file indexing all the resources of

your project. You use this class in your source code as a sort of short-

hand way to refer to resources you've included in your project. This is

particularly powerful with the code-completion features of IDEs like

Eclipse because it lets you quickly and interactively locate the specific

reference you're looking for. Additionally you gain compile-time safety that the resource you want to use really exists.

项目的R.java文件是一个自动生成的编制索引的所有资源的文件。您在您的源代码中使用这些类来声明您在工程中要使用的资源。使用强大的有代码完成功能的比如Eclipse

将更加容易的实现,因为它让您更快更准确地定位您要寻找的资源。

另外您可以让您的资源文件在编译时更加安全。

Hello World – The Android way.

In this very first tutorial one will learn how to create an Android

Application using a XML layout. Keep in mind that, using XML-Layouts is

highly preferable!

What it will finally look like:

Picture 6 First Android Application - Final look (sdk-version: m5)

But before all that one needs to download and install the Android SDK…

Installing the Android SDK

The latest Android SDK for Windows, Mac and Linux can always be

obtained from the following URI:

http://code.google.com/android/download.html

It only needs to be downloaded and unzipped to your preferred hdd-

location.

The Android Development Tools (ADT)

Android provides an Eclipse plugin called ‘ADT’ to make programming

and debugging easier.

The ADT provides easy access to the LogCat, the Android-

Manifest/Resource-Editor, File, Thread, and Heap Control, incoming

call/sms simulation, etc… – since SDK-version m5 all for multiple

emulator instances at the same time.

Installing the Eclipse Plugin (ADT)

To download and install the ADT plugin, follow the steps Google provides

to developers:

1. Start Eclipse, then select Help > Software Updates > Find and

Install....

2. In the dialog that appears, select Search for new features to

install and press Next.

3. Press New Remote Site.

4. In the resulting dialog box, enter a name for the remote site (e.g.

Android Plugin) and enter this as its URL:

https://dl-ssl.google.com/android/eclipse/

Press OK.

5. You should now see the new site added to the search list (and

checked). Press Finish.


6. In the subsequent Search Results dialog box, select the checkbox

for Android Plugin > Developer Tools. This will check both

features: "Android Developer Tools", and "Android Editors". The

Android Editors feature is optional, but recommended. If you

choose to install it, you need the WST plugin mentioned earlier in

this page.

Now press Next.

7. Read the license agreement and then select Accept terms of the

license agreement, if appropriate. Press Next.

8. Press Finish.

9. The ADT plugin is not signed; you can accept the installation

anyway by pressing Install All.

10. Restart Eclipse.

11. After restart, update your Eclipse preferences to point to the

SDK directory:

a. Select Window > Preferences... to open the Preferences

panel. (Mac OS X: Eclipse > Preferences)

b. Select Android from the left panel.

c. For the SDK Location in the main panel, press Browse...

and locate the SDK directory.

d. Press Apply, then OK.

Updating the ADT Plugin

Updating the ADT Plugin follows the standard procedure of upgrading a

common Eclipse plugin:

1. Select Help > Software Updates > Find and Install....

2. Select Search for updates of the currently installed features and

press Finish.

3. If any update for ADT is available, select and install.


Installation done, let’s do some code

Before we can start coding we obviously have to create a new Android

Project.

Creating a new Android Project

1. The first thing that needs to be for every Android Application is

to create a new Android Project. To do that, simply open

the Package Exlporer in Eclipse right-click on some blank space

and choose:

New > Project…

Picture 7 First Android Application - Step 1

2. Select:

Android > Android Project


Picture 8 First Android Application - Step 2

3. Fill out the form with values fitting your applications purpose...

Picture 9 First Android Application - Step 3


4. This are all the files for your first Android-Application (don't

panic, mostly all of them are resource-files)

Picture 10 First Android Application - Step 4

Huh, what are all that files supposed to do ?

As you now have created your first Android Project you will see a bunch

of files appear in that new project.

The Main Activity

You’ll see some default code like the following, when you now navigate

to:

/src/your_package_Structure/Hello_Android.java”

package org.anddev.android.Hello_Android;

import android.app.Activity;

import android.os.Bundle;

public class Hello_Android extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

/* Make this application use

* the main.xml-layout-file. */

this.setContentView(R.layout.main);

}

}


run.png

We could now immediately our Application but let me explain of the

other files too.

The XML-Layout (main.xml)

The ADT created this very basic Activity for you. As we know Activities

are somehow like JFrames in Swing. In Android we extend from Activity

and need to overwrite a single function, called onCreate(…). Within

this function we have to call i.e.

setContentView(R.layout.main)which makes our Activity use

the main.xml which was also created by the ADT:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Hello World, Hello_Android"/>

</LinearLayout>

We have a ‘fullscreen’ vertical LinearLayout, that contains a single

TextView showing a pre-defined String.

The AndroidManifest.xml

So let’s face the AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="org.anddev.android.hello_android">

<application android:icon="@drawable/icon">

<activity android:name=".Hello_Android"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category

android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

</manifest>


Let’s split that up…

Every xml-file starts with the following line, it defines the xml-version and

encoding-type of the xml-text. Just copy-paste it to every new file.

<?xml version="1.0" encoding="utf-8"?>

As we know the outermost tag in every xml-file should contain this

attribute:

xmlns:android="http://schemas.android.com/apk/res/android"

Because it makes a variety of general Android attributes available in the

file.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="org.anddev.android.hello_android">

.....

</manifest>

The <application> tag is the root element containing declarations of

all application-level components contained in the package. This element

can also include global and/or default attributes for the application, such

as a label, icon, theme, required permission, etc…

Here we define just the icon, by making a ‘@-refer’ to a image placed

under "/res/drawable/".

<application android:icon="@drawable/icon">

.....

</application>

Inside of the <application> tag we need to define all

Activities/IntentReceivers that need to be started via Intents. In this case

we have only one simple Activity.

<activity android:name=".Hello_Android"

android:label="@string/app_name">

.....

</activity>


exclamation.gif

You probably have recognizes that the package-attribute from the

<manifest> tag together with the android:name attribute from

the <activity> tag always result in the complete package-path to the

Activity described.

The innermost tag is the <intent-filter> tag which defines on

which Intents we want to listen. Here we want the Hello_Android Activity

launchable from within the emulator by clicking the icon (that was

defined in the <application> tag).

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category

android:name="android.intent.category.LAUNCHER" />

</intent-filter>

Note: The debugging-process with a Android Application is

exactly the same than with a normal Java Application.


run.png

run.png

open_run_dialog.png

run_dialog.png

Running your first application

Now we need to create a ‘-Configuration’. Open the -DropDown in

the Eclipses upper menu and Click "Open Run Dialog..."

Picture 11 Opening the run-dialog

Picture 12 Creating a run-configuration


run.png

app_added.png

From now on you can run your application by clicking the button.

Having done that you’ll see this:

Picture 13 First Android Application - The result (sdk-version m5)

After the first deploy you can also see your application being listed in the

quick-menu, displayed with the default icon:

Picture 14 First Android Application - Added to QuickMenu (sdk-version m5)


UIs the Java way

The same thing as we have just done with XML-Code can be achieved by

hacking some lines of Java-Code.

Remember how we set our main.xml as the ContentView in the xml-

example. We accomplished that by doing the following:

/* Make this application use

* the main.xml-layout-file. */

this.setContentView(R.layout.main);

Activity.setContentView(…) also accepts a View as the

parameter. We will use that to set a simple TextView as our

ContentView.

package org.anddev.android.Hello_Android;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class Hello_Android extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

/* We want to view some very simple text,

* so we need a TextView associated with this Activity. */

TextView tv = new TextView(this);

/* Put some text to the newly created TextView */

tv.setText("Hello Android - by: anddev.org /n" +

"This is soooo simple =D ");

/* Tell our Activity to display that TextView */

this.setContentView(tv);

}

}


open_ddms_view.png

System.out.println(…) ?

Debugging in Android cannot be done using

System.out.println(…) because as we know Android is not

running on a normal VM but inside of emulated hardware on the

DalvikVM. ( To be honest, it can be done but is should definitely be not

your choice)

But don’t worry, Android provides a much more powerful debugging

feature – The LogCat.

The LogCat

The LogCat is a part of the DDMS (Dalvik Debug Monitor service) that

provides a mechanism for collecting and viewing system debug output.

Logs from various applications and portions of the system are collected in

the LogCat, which then can be viewed and filtered.

If you cannot see A, do it the B way.

Picture 15 Opening the DDMS View

Using the LogCat

Every Android log message has a tag and a priority associated with it.


logcat.png

The tag of a log message is a short string indicating the system

component from which the message originates (for example, "View" for

the view system).

The priority is one of the following character values, ordered from lowest

to highest priority:

. V — Verbose (lowest priority)

. D — Debug

. I — Info

. W — Warning

. E — Error (highest priority)

As we are using Eclipse we can simply filter by priority clicking the “V-D-I-

W-E” Buttons in the LogCat View one can also see below. You’ll love the

ADT plugin for that feature, because, in the masses of output the whole

system generates, it is really hard to find anything without filters.

Picture 16 The LogCat

The usage in the code is pretty simple. You need to make a single import:

import android.util.Log;

Then you are able to use debugging statements, like this:

Log.d("DEBUGTAG", "My debug-message.");


When some critical things happened you can pass the

Throwable/Exception to Log.e(…),to get the StackTrace printed

to the LogCat:

try{

throw new Exception();

}catch(Exception e){

Log.e("DEBUGTAG","Error occured", e);

}

Note:


Using Intents

As we know things needed to be done are expressed by Intents. Intents

can i.e. be used to start other Activities.

Starting (Sub)Activities

An essential thing in the lifetime of an application, that is more

sophisticated than a HelloWorld Application, is to start other Activities,

especially SubActivitites. Let’s assume the following scenario:

We want to have something like an InputDialog where the user can write

a keyword he wants to search on Google for.

So we will create a new Android Project as we already did it before. The

first thing we will do is to add a second Activity we will name

MySecondActivity”.

In the beginning the code shall look like this:

package org.anddev.andbook.startingsubactivities;

import android.app.Activity;

import android.os.Bundle;

public class MySecondActivity extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

}

}


open_resource_editor.png

layout_start.png

We now will add a Button to the first Activity. We do that by altering the

main.xml, of course, and not by switching to a Java UI.

Browse to “/res/layout/main.xml” and you will see code similar

to this:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Hello World, StartingSubactivities" />

</LinearLayout>

Note: maybe Eclipse opened the main.xml with its default xml-Editor which is

not of any use for us. Since SDK-version m5 the ADT plugin provides a

Resource-Editor with Syntax-Highlighting.

Picture 17 Opening the Resource Editor

If we would start the Application right now it would look like this:

Picture 18 Layout default (sdk-version m5)


layout_with_button.png

As we want to have a Button in our application, we will have to come up

with some xml-code:

<Button

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Open Search-Dialog" />

As one can imagine, “fill_parent” makes a View us all space the

parent View provides and “wrap_content” uses just as much layout

space as it needs to display its content correctly.

So our button will fill the whole screen in width and wrap around the

Open Search-Dialog” we typed for the android:text attribute.

Our application now looks like this:

Picture 19 Layout with Button (sdk-version m5)

When we now click the button – nothing happens, of course. We will

have to apply a Listener to be specific an OnClickListener to Handle clicks

to this Buttons.

But wait… how can we refer to that Button in Java Code ?


exclamation.gif

Finding XML-defined Views in Java-Code

To find a View that was defined in XML we first have to add one single

line to the XML-definition of that View, an android:id attribute. In

this case we will give it the id “btn_open_search”:

<Button

android:id="@+id/btn_open_search"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Open Search-Dialog" />

Finding that View in Java Code is same easy. Within an Activity you can

use the findViewById(int resourceID) method, to get a

reference to a View using the android:id that has been defined in

XML.

The same can be done with any other class that extends View, i.e.

EditText, TextView, MapView, etc…

But findViewById(…) can only be used with Views that are

placed within the Layout that was loaded to that Activity using

setContentView(…)!

Coming back to our example, we add the following in Code to

onCreate(…), right after the setContentView(…):

/* Find the Button from our XML-layout. */

Button b = (Button)this.findViewById(R.id.btn_open_search);

If Eclipse cannot find i.e. the Button-Class, just hit ‘CTRL+SHIFT+O’

what will organize the imports and automatically add (in this case):

import android.widget.Button;


wink.gif

Handling Clicks to Views

We now remember that we once wanted to make our button

clickable. Therefore we simply set an anonymous OnClickListener

to our Button:

b.setOnClickListener(new OnClickListener(){

public void onClick(View arg0) {

// Place code to handle Button-Click here.

}

});

Note: Eclipse might not recognize the following import by itself:

import android.view.View.OnClickListener;

Now we will add an Intent to the onClick-Event that will start our

SubActivity:

/* Create an Intent to start

* MySecondActivity. */

Intent i = new Intent(

StartingSubactivities.this,

MySecondActivity.class);

/* Send intent to the OS to make

* it aware that we want to start

* MySecondActivity as a SubActivity. */

startSubActivity(i, 0x1337);

The second parameter of startSubActivity can be any unique

Integer. It will get useful later on (then we will be placing it declared as

final to our Activity), when we want to retrieve a result from the

SubActivity.


activity_not_defined_in_manifest.png

exclamation.gif

If we would now run our code and click our button we would receive the

following error-message:

Picture 20 Activity not defined in AndroidManifest.xml

Note: Some of the messages shown are really helpful, read them.

So we need to define our “MySecondActivity” in the

AndroidManiufest.xml too. Just after the first </activity> tag

we write:

<activity android:name=".MySecondActivity"

android:label="@string/app_name">

<intent-filter>

<action

android:name="android.intent.action.VIEW" />

<category

android:name="android.intent.category.DEFAULT" />

</intent-filter>

</activity>

This time we did not choose “…MAIN” for <action> and

“…LAUNCHER” for <category> because there is no need to get

MySecondActivity” launched from outside of our Application.


MySecondActivity” is now reachable through a click to the button,

but it also refers to our main.xml:

setContentView(R.layout.main);

So we have to create an additional layout file for

MySecondActivity”. It will contain a so called EditText what in

Swing jargon would be a TextField and another Button to return to

our “Main”-Activity:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<EditText

android:id="@+id/et_keyword"

android:layout_width="fill_parent"

android:layout_height="wrap_content"/>

<Button

android:id="@+id/btn_return"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Submit" />

</LinearLayout>

Of course both need an android:id that we can use the in our

JavaCode. Now we can change the setContentView of

MySecondActivity” to:

/* Get the EditText from the XML-file. */

this.et_keyword = (EditText)this.findViewById(R.id.et_keyword);

/* Get the return-Button from the XML-file. */

Button b = (Button)this.findViewById(R.id.btn_return);

/* Make that Button handle clicks to itself. */

b.setOnClickListener(new OnClickListener(){

public void onClick(View arg0) {

/* Place code to handle Button-Click here. */

}

});


Returning values from SubActivities

Returning values from SubActivities to the caller is also very simple:

/* Retrieve the Text from the EditText. */

String keyword =

MySecondActivity.this.et_keyword.getText().toString();

/* The parameters passed to this function

* will be available to the caller. */

MySecondActivity.this.setResult(1, keyword);

/* Our Activity is done and shall be closed. */

MySecondActivity.this.finish();

One could additionally pass a so called Bundle back to the caller (what

is more or less a HashMap), but I’ll tell you more of that soon.

Obviously the caller has to react on the fact that the SubActivity decided

to return. To accomplish that, we have to override a single method

coming from the Activity class. It is called onActivityResult(…):

@Override

protected void onActivityResult(int requestCode, int resultCode,

String data, Bundle extras) {

/* Place out code to react on Activity-Result here. */

super.onActivityResult(requestCode, resultCode, data, extras);

}

You probably recognized that the first parameter is called

requestCode – yes it is the same requestCode that we passed to

startSubActivity earlier. So if we have more than one SubActivity,

we can use requestCode to differentiate which SubActivity has just

returned.

Tipp: Eclipse provides a very useful function that you’ll learn to love,

especially if you are extending a base-class and search for methods to

override:


trick_override_methods.png

Picture 21 Using Eclipse to find methods to override

So now we can simply switch on the requestCode and create another

Intent to do the Google-search.

/* Check which SubActivity returned.

* (Here we have only one.) */

switch(requestCode){

case MYSECONDACTIVITY_REQUESTCODE:

/* Create a new Intent to

* show the Google-Search Page

* with the keyword returned. */

Intent webIntent = new Intent(

android.content.Intent.VIEW_ACTION,

Uri.parse("http://www.google.com/search?q=" + data));

startActivity(webIntent);

break;

}

As you probably have recognized this time we are creating the Intent

another way. Last time we said like: “We want to start XYZ.class“,

but this time we describe what we want to get done. We want to VIEW a

URI (Uniform Resource Indicator), which can be constructed by using i.e.

Uri.fromParts(…).

Our Application is now capable of starting a (Sub)Activity, grabbing its

results and launching the Browser using an Intent.

But how to pass data to a (Sub)Activity?


Passing Data to (Sub)Activities

Passing data to (Sub)Activities is, once again, not hard to manage. One

can use so called Bundles, which are more or less ordinary HashMap’s

that can take only trivial data types, to carry information from one

Activity to another. Just remember where we started our SubActivity in

the last chapter:

/* Create an Intent to start

* MySecondActivity. */

Intent i = new Intent(

StartingSubactivities.this,

MySecondActivity.class);

/* Send intent to the OS to make

* it aware that we want to start

* MySecondActivity as a SubActivity. */

startSubActivity(i, 0x1337);

Right between these two lines, we will put the following:

/* Create a bundle which will be

* attached to the Intent, to carry

* information to our SubActivity. */

Bundle b = new Bundle();

b.putString(MY_DEFAULTSTRING_ID, "anddev.org");

/* Attach Bundle to our Intent. */

i.putExtras(b);

Where MY_DEFAULTSTRING_ID can be any identifying String you can

imagine. There is also a method Intent.putExtra(…,…) which takes only

one information each call, which we could have used also.


smile.gif

Now we have to extract that information within our SubActivity. Every

Activity can access the original Intent it was started with, by calling

getIntent(). If there was a Bundle attached to the Intent we can

grab that by using getIntent().getExtras(). In this case we, we

will fill the EditText, where the user would type the keyword(s) with

the DefaultString we passed over the Intent :

//…

setContentView(R.layout.second);

/* Get the Bundle from the Intent

* this Activity was started with.*/

Bundle bundle = getIntent().getExtras();

/* Extract the default keyword

* by using the public ID we

* defined in the caller. */

String default_keyword = bundle.getString(

StartingSubactivities.MY_DEFAULTSTRING_ID);

/* Get the EditText from the XML-file. */

this.et_keyword = (EditText)this.findViewById(R.id.et_keyword);

/* Set the default keyword to the EditText. */

this.et_keyword.setText(default_keyword);

/* Get the return-Button from the XML-file. */

//…

So let’s resume what you have learned up to here:

. Create an simple Application using a XML Layout

. Do the same with a Java-based Layout

. Run Android Applications

. Using the LogCat for debugging purpose

. Use Intents to start (Sub)Activities

. Find Views defined in XML to use them in Java Code

. Handle Clicks to Views

. Return values from SubActivities

. Pass data to SubActivities using Bundles

Not bad for now .


Important Layouts and ViewGroups

Android provides many more Layouts than just the LinearLayout we used

up to here. The most important Layouts, except LinearLayout, you will

get to know closer here are:

. RelativeLayout (Views are placed relative to each other)

. TableLayout (Uses tables like in HTML)

Additionally to that I will introduce to you the following really often used

ViewGroups:

. GridView (similar to TableLayout, supports ‘Adapters’)

. ScrollView (If your content exceeds the screen-size, you’ll need

to scroll)

. TabHost (Displays content in tabs)

The RelativeLayout

According to its name, when using RelativeLayouts one defines the

position of Views relative to other ‘neighbors-Views’.


Bibliography

1. Open Hanset Alliance. Open Hanset Alliance. [Online]

http://www.openhandsetalliance.com/.

2. GoogleGroups. Android Discussion Groups. [Online]

http://code.google.com/android/groups.html.

3. Alexa Webstats. The Web Information Company. alexa.com. [Online]

http://www.alexa.com.

4. Gramlich, Nicolas. Android Development Community | Android

Tutorials. [Online] http://anddev.org.

5. Hobbs, Zach. Hello Android. [Online] http://helloandroid.com/.

6. Nguyen, Vincent. Android Community. [Online]

http://androidcommunity.com/.

7. Srinivas, Davanum. Show me the code! [Online]

http://davanum.wordpress.com/.


Lost chapters

The communities

From the first day on, a couple of communities arose from the depth of

the internet. The most important community-website to mention

(depending on Alexa-stats (3)) is anddev.org (4) , which is the most

viewed Tutorial/Community-Board for Google Android up to date. Also

well known are the Community-Boards: helloandroid.com (5) and

androidcommunity.com (6). Last but definitely not least to mention is the

davanum.wordpress.com-Blog (7), which provided some very early

sample code where many programmers found a good first source.

Some sites were more, some less promising, so sooner or later the

viewers pointed their focus to the more-important sites listed above.


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics