1 / 48

Android 应用开发

Android 应用开发. 2010 年 8 月 13 日. 目录. Android 平台架构. Android 环境配置和开发. Android 应用程序构成. 如何开发一个例子. Android 平台架构. JAVA. JNI. C/ 汇编. 简介. Linux 核心 : Android 依赖 Linux 2.6 来 提供核心的 服务 ,例如 存储 管理、 进程 (Process) 管理等 Android Runtime : Java 语言层级的 Virtual Machine

chace
Télécharger la présentation

Android 应用开发

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Android应用开发 2010年8月13日

  2. 目录 Android平台架构 Android环境配置和开发 Android应用程序构成 如何开发一个例子

  3. Android平台架构 JAVA JNI C/汇编

  4. 简介 • Linux核心:Android依赖Linux 2.6来提供核心的服务,例如存储管理、进程(Process)管理等 • Android Runtime:Java语言层级的Virtual Machine • Libraries:Android里已经提供的C/C++组件。例如,SQLite、OpenGL 3D等。 • 应用框架(Application Framework,):这是结合Applications和Libraries的主架构,让Libraries組件能不断地为Applications所重复使用 • 应用程序(Applications):根据用户的期望而将AF的组件及Libraries组件组合而成的服务。

  5. 用汉堡比喻Android 平台架构

  6. 目录 Android平台架构 Android环境配置和开发 Android应用程序构成 如何开发一个例子

  7. 如何安装 Android SDK 和Eclipse 插件 所需开发环境: JDK 5 或 JDK 6 (仅有JRE不够) Eclipse 3.5 (galileo) 下载ADT 的Eclipse 插件 http://dl.google.com/android/ADT-0.9.5.zip 安装 Eclipse 插件 (ADT) 启动 Eclipse,选择 Help > Install New Software,在出现的对话框里,点击Add按钮,在对话框的name一栏输入“ADT”, 然后点击Archive...,浏览和选择已经下载的ADT插件压缩文件。 点击 OK.。返回可用软件的视图,你会看到这个插件,然后选择Developer Tools (会选中下面的“Android Developer Tools”和 “Android Editors“),点击 Next,最后重启 Eclipse。 下载Android SDK: http://dl.google.com/android/android-sdk_r04-windows.zip 下载完SDK后,把.zip文件解压到你电脑上合适位置。启动 Eclipse,选择window->preferences,在打开的视图左边点击android,在右边的SDK Location中选择Android SDK所在位置。

  8. 开发第一个Android应用 打开Eclipse,新建项目(点击FileNewProject),在项目列表中展开Android目录,选择Android Project,如下图:

  9. 开发第一个Android应用

  10. 开发第一个Android应用 点击”finish”即可完成项目的创建,创建后的项目已经是一个可运行的Android应用,我们可以通过下面方式运行此应用: 点击工具栏上手机形状的虚拟设备管理器(简称“AVD“),如下:

  11. 开发第一个Android应用 在打开的虚拟设备管理器中创建一个虚拟手机:

  12. 开发第一个Android应用 在项目上右键点击run as Android application,如下图:

  13. Android应用程序架构 src/ java原代码存放目录 gen/ 自动生成目录 gen 目录中存放所有由Android开发工具自动生成的文件。目录中最重要的就是R.java文件。 这个文件由Android开发工具自动产生的。Android开发工具会自动根据你放入res目录的xml界面文件、图标与常量,同步更新修改R.java文件。正因为R.java文件是由开发工具自动生成的,所以我们应避免手工修改R.java。R.java在应用中起到了字典的作用,它包含了界面、图标、常量等各种资源的id,通过R.java,应用可以很方便地找到对应资源。另外编绎器也会检查R.java列表中的资源是否被使用到,没有被使用到的资源不会编绎进软件中,这样可以减少应用在手机占用的空间。 res/ 资源(Resource)目录 在这个目录中我们可以存放应用使用到的各种资源,如xml界面文件,图片或数据。具体请看ppt下方备注栏。 AndroidManifest.xml功能清单文件 这个文件列出了应用程序所提供的功能,在这个文件中,你可以指定应用程序使用到的服务(如电话服务、互联网服务、短信服务、GPS服务等等)。另外当你新添加一个Activity的时候,也需要在这个文件中进行相应配置,只有配置好后,才能调用此Activity。 default.properties项目环境信息,一般是不需要修改此文件

  14. 目录 Android平台架构 Android环境配置和开发 Android应用程序构成 如何开发一个例子

  15. Android应用程序构成 Activity Service Intent Broadcast Receiver Content Provider

  16. Activity • A visual user interface • 通过view管理UI • 每一个有用户界面的应用至少包含一个activity • 一个应用可以有多个activity,其中一个作为main activity用于启动显示 • Activity通过startActivity或startActivityForResult启动另外的activity

  17. Activity生命周期 • Activity通过onCreate被创建 • 当一个activity失去焦点,该activity将进入pause状态,系统在内存不足时会将其终止 • 当一个activity被另一个activity覆盖,该activity将进入stop状态,系统在需要内存的时候会将其终止

  18. Intent • 类似于消息、事件通知 • Intent构成:action、category、data • Activity、Service、broadcast receiver之间的桥梁 activity service Intent Broadcast receiver

  19. Intent • 两类intent: • 显式:指定具体的目标组件处理 • startActivity(new Intent(ActivityLifecycle.this, AnotherActivity.class)); • 隐式:由系统接受并决定如何处理 • startActivity(new Intent(Intent.ACTION_DIAL)); • 在AndroidManifest.xml中定义activity、service、broadcast receiver接受的intent

  20. Intent • Intent filter: action、category、data Component name Action Data Category activity service framework component Broadcast receiver intent

  21. 实例 action -- DIAL data -- tel:01038639592 action -- VIEW data -- http://www.google.cn

  22. Service • 没有UI,启动之后一直运行于后台 • 例子:音乐播放器 • 与应用程序的其他模块(例如activity)一同运行于主线程中 • 通过startService或bindService创建Service • 通过stopService或stopSelf终止Service • 一般的,在activity中启动和终止service

  23. Service生命周期 Context.startService() Context.bindService() Context.stopService() Serivce.stopSelf()

  24. 服务--Service Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。服务的开发比较简单,如下: 第一步:继承Service类 public class SMSService extends Service { }

  25. 服务--Service 第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置: <service android:name=".SMSService" /> 服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。 如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

  26. 服务--Service 如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。

  27. 服务--Service 服务常用生命周期回调方法如下: onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。 onDestroy()该方法在服务被终止时调用。 • 与采用Context.startService()方法启动服务有关的生命周期方法 onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。 • 与采用Context.bindService()方法启动服务有关的生命周期方法 onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。 onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。

  28. 采用startService()启动服务 采用Context.startService()方法启动服务的代码如下: public class HelloActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { ...... Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(HelloActivity.this, SMSService.class); startService(intent); }}); } }

  29. 采用bindService()启动服务 采用Context.startService()方法启动服务的代码如下: public class HelloActivity extends Activity { ServiceConnection conn = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder service) { } public void onServiceDisconnected(ComponentName name) { } }; @Override public void onCreate(Bundle savedInstanceState) { Button button =(Button) this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(HelloActivity.this, SMSService.class); bindService(intent, conn, Context.BIND_AUTO_CREATE); //unbindService(conn);//解除绑定 }}); } }

  30. 何为Content provider • 什么是Content provider? • Content Provider 是Android应用程序的四大组成部分之一 • 是android中的跨应用访问数据机制 • 为何需要content provider? • Android中每一个app的资源是私有的 • app通过content provider和其他app共享私有数据

  31. 如何使用content provider • 通过content resolver访问 • Context.getContentResolver() app app app ContentResolver ContentResolver ContentResolver ContentProvider A ContentProvider B

  32. 如何使用content provider • URI定位资源 • content://contacts/people • content://call_log • 类似关系数据库的访问方式 • 以二维数据表的格式暴露数据,缺省都包含_id字段 delete(Uri url, String where, String[] selectionArgs) insert(Uri url, ContentValues values) query(Uri uri, String[] projection, String selection,  String[] selectionArgs, String sortOrder) update(Uri uri, ContentValues values, String where,  String[] selectionArgs)

  33. 定义自己的content provider

  34. Android的存储 • 一般的,应用程序的数据(包括文件)都是私有的 • 四种持久存储方式 • Preferences——类似properties,xml文件 • Files • Database——SQLite • Network

  35. Broadcast receiver • 接收和处理android的广播消息 • Android的广播机制 • 系统事件——例如变换时区、电量低等 • 应用程序发出广播消息:sendBroadCast • 广播消息:intent android Send broadcast Broadcast receiver app

  36. 创建Broadcast Receiver • 实现一个BroadcastReceiver • public class MyAndroidReceiver extends BroadcastReceiver • override onReceive(Context context, Intents Intents) • 注册BroadcastReceiver • 在AndroidManifest.xml文件当中进行注册 • 在代码当中直接进行注册 <receiver Android:name=“MyAndroidReceiver"> <Intents-filter> <action Android:name=”com.eoeAndroid.action.NEW_BROADCAST”/> </Intents-filter> </receiver> IntentsFilter filter = new IntentsFilter(NEW_BROADCAST ); MyAndroidReceiver MyAndroidReceiver = new MyAndroidReceiver(); registerReceiver(MyAndroidReceiver , filter);

  37. Broadcast receiver生命周期 Broadcast receiver对象在onReceive返回后被销毁 onReceive中不适合处理异步过程。例如弹出对话框与用户交互,可使用消息栏替代。

  38. Android权限控制 • 在AndroidManifest.xml中描述一个app的权限 • 例如: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.app.myapp" > <uses-permission android:name="android.permission.RECEIVE_SMS" /> </manifest> • 权限举例(参考android. Manifest.permission)

  39. 目录 Android平台架构 Android环境配置和开发 Android应用程序构成 如何开发一个例子

  40. 从Internet获取数据 利用HttpURLConnection对象,我们可以从网络中获取网页数据. URL url = new URL("http://www.sina.com"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(6* 1000);//设置连接超时 if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败"); InputStream is = conn.getInputStream();//得到网络返回的输入流 String result = readData(is, "GBK"); conn.disconnect(); System.out.println(result); //第一个参数为输入流,第二个参数为字符集编码 public static String readData(InputStream inSream, String charsetName) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while( (len = inSream.read(buffer)) != -1 ){ outStream.write(buffer, 0, len); } byte[] data = outStream.toByteArray(); outStream.close(); inSream.close(); return new String(data, charsetName); }

  41. 从Internet获取数据 利用HttpURLConnection对象,我们可以从网络中获取文件数据. URL url = new URL("http://sinaapp.com/Img269812337.jpg"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(6* 1000); if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败"); InputStream is = conn.getInputStream(); readAsFile(is, "Img269812337.jpg"); public static void readAsFile(InputStream inSream, File file) throws Exception{ FileOutputStream outStream = new FileOutputStream(file); byte[] buffer = new byte[1024]; int len = -1; while( (len = inSream.read(buffer)) != -1 ){ outStream.write(buffer, 0, len); } outStream.close(); inSream.close(); }

  42. 向Internet发送请求参数 利用HttpURLConnection对象,我们可以向网络发送请求参数. String requestUrl = "http://localhost:8080/itcast/contanctmanage.do"; Map<String, String> requestParams = new HashMap<String, String>(); requestParams.put("age", "12"); requestParams.put("name", "中国"); StringBuilder params = new StringBuilder(); for(Map.Entry<String, String> entry : requestParams.entrySet()){ params.append(entry.getKey()); params.append("="); params.append(URLEncoder.encode(entry.getValue(), "UTF-8")); params.append("&"); } if (params.length() > 0) params.deleteCharAt(params.length() - 1); byte[] data = params.toString().getBytes(); URL realUrl = new URL(requestUrl); HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();

  43. 向Internet发送请求参数 conn.setDoOutput(true);//发送POST请求必须设置允许输出 conn.setUseCaches(false);//不使用Cache conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive");//维持长连接 conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty("Content-Length", String.valueOf(data.length)); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); DataOutputStream outStream = new DataOutputStream(conn.getOutputStream()); outStream.write(data); outStream.flush(); if( conn.getResponseCode() == 200 ){ String result = readAsString(conn.getInputStream(), "UTF-8"); outStream.close(); System.out.println(result); }

  44. =向Internet发送xml数据 利用HttpURLConnection对象,我们可以向网络发送xml数据. StringBuilder xml = new StringBuilder(); xml.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>"); xml.append("<M1 V=10000>"); xml.append("<U I=1 D=\"N73\">中国</U>"); xml.append("</M1>"); byte[] xmlbyte = xml.toString().getBytes("UTF-8"); URL url = new URL("http://localhost:8080/itcast/contanctmanage.do?method=readxml"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(6* 1000); conn.setDoOutput(true);//允许输出 conn.setUseCaches(false);//不使用Cache conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive");//维持长连接 conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty("Content-Length", String.valueOf(xmlbyte.length)); conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8"); DataOutputStream outStream = new DataOutputStream(conn.getOutputStream()); outStream.write(xmlbyte);//发送xml数据 outStream.flush(); if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败"); InputStream is = conn.getInputStream();//获取返回数据 String result = readAsString(is, "UTF-8"); outStream.close();

  45. HTTP多线程断点下载应用程序 • 多线程下载:

  46. HTTP多线程断点下载应用程序 • 如何才能从文件的指定位置处开始下载文件?(比如从50MB开始)这一点我们可以通过HTTP请求信息头来设置,可以使用HTTP请求信息头的“Range”属性。 例如:只要在请求头中加入以下代码就可以只请求部分数据: Content-Range: bytes 20000-40000/47000 ,即从第20000字节请求到第40000个字节,(文件长度是47000字节)

  47. HTTP多线程断点下载应用程序 • 如何支持断点下载。就是将下载的进度保存到文件中,但在Android中却不能这么做。在Android平台中,我们需要向文件中写出下载的文件数据,我们通过数据库的方式保存下载进度

  48. 谢谢!

More Related