android知识点总结

项目目录结构


项目目录结构项目目录结构


项目目录结构: 


Src: java.class源文件 


Gen: Android开发工具自动生成.自动维护,不能修改 


R.java 不能手工修改此类中的内容记录各种资源的ID 可以根据R文件中的ID查找各个方法 


Assets: 存放资源文件.但存放的资源不会在R.java中生成ID 


  必须指定路径才能引用其中的文件 


Res: 存放各种资源文件. 


 drawable-hdpi: 


  里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854) 


 drawable-ldpi: 


  里面存放低分辨率的图片,如QVGA (240x320) 


 drawable-mdpi: 


  里面存放中等分辨率的图片,如HVGA (320x480) 


在分辨率低于480*800时把图片放在drawable—mdpi中是不会有什么影响,但是当分辨率为420*800或高于它时就会出问题了。你的手机


屏幕有那么大但是他会将图片拉伸,当加载图片后让你感觉该屏幕没有实际的大小,而如果将图片放到drawable—hdpi中则该问题就不会


存在了。比如手机屏幕的大小为420*800如果你将图片放在drawable—mdpi中,那么你就要准备一张340*525分辨率的图片, 


  系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。 


 layout: 


   main.XML界面资源 


 Values: 


 <resources>为根节点 </resources> 


<string>通过string指定</string> 


   String.XML应用中文字,尺寸,颜色等数据 


Default.properties :系统文件 


AndroidManifest.XML:项目清单文件.配置文件. 权限配置. 布局控件


 <Gallery>: 画廊式 TabWidget>:切换卡 TextView>:文本框 <button>:按钮控件 


<EditText>:编辑框. EditText.setHint(“设置默认背景内容”)—XML设置:android:hit=” 设置默认背景内容” 


<imageView>:图片显示控件 


@+id/button :在R文件内的ID中内部类添加常量button.引用button为Button的ID 


FindViewbyid(R.id.button);   //获取按钮 


Setonclicklistener();  //获取点击事件 


Gettext().toString();  //获取用户在文本框中输入的数据.转换为字符串 


Android:gravity=”XXx” –重心偏移 


Android:minLines =”3”; //指定文本框的高度. 


<EdiTest>控件: 


Android:numecic: 限制文本框只能输入数字 


Android:phoneNumber=”true”  只接收电话号码 


<Button>控件: 


<ImageButton> <ImageButton>设置按钮图标使用 


Android:Onclick=”query” 当用户点击按钮时,调用query中的点击方法 


自动适应屏幕的模式,横竖屏自动转换: 


<activity android:name=”.Acitivty” 


  Android:label=string/app_name”   Android:screenOrientation=”sensor”>


Android:layout_weigth=”0-??” 确定显示控件优先确定


< HorizontalScrollView> :


水平滑动布局 


RandOmAccessFile:随即文件访问方法 


<ProgressBar>进度条设置Style=”@android:style


 


在Android中,应用的响应性被活动管理器(Activity Manager


和窗口管理器(Window Manager)这两个系统服务所监视


当用户触发了输入事件(如键盘输入,点击按钮等


如果应用5秒内没有响应用户的输入事件,那么


为该应用无响应,便弹出ANR(Application No Response


在正常情况下,Android程序会在一条单线程里运行


被阻塞,后面的用户输入事件因没能在5秒内响应


 


应用程序的4个模块构成: 1.


 Activity(活动窗口):监听各种系统事件 


对话框主题:  <activity android:name = “.activity


 多个Activity同时出现在一个程序中需要在void onCreate


(Bundle savedInstanceState)onCreate()


onCreate()onCreate()


onCreate()  onStart()-   onResume创建-   开始-     恢复- 


Task:启动模式:android:launchMode 


Standard: 每次访问实例化新的. 


singleTop: 每次访问,看栈顶元素是目标对象


singelTask: 保证activity实例化一次,单任务





确定显示控件优先确定 默认为0,0为最大 


@android:style 


Activity Manager)  


这两个系统服务所监视。  


点击按钮等),  


那么,Android会认  


Application No Response)  


程序会在一条单线程里运行。如果Activity要处理一件比较耗时的工作,应该交给子线程完成


秒内响应,导致应用出现ANR对话框。  


 


.activity” android:theme=”@android:stsyle/Theme.Dialog”/> 


同时出现在一个程序中需要在AndroidManifest.xml 申请配置 


 (Bundle savedInstanceState)


 onResume()-   onPause()-  onStop()-  onDestroy   暂停-       停止-       销毁


看栈顶元素是目标对象,是则返回,不再实例化,否则,还是实例化. 


单任务,由此所开启的活动和本活动位于同一task中 . 


应该交给子线程完成,否侧会因为主线程


 


 onDestroy


() 销毁 singelInstance: 保证activity实例化一次,单实例,由此所开启的活动在新的task中,和本活动id不一致. 


三种状态: 


 运行状态: 处于激活状态,能够响应用户操作 触发onCreate();onstart();onresume(); 


 暂停状态: 被新应用部分覆盖,用户仍然可见,; 触发onPause();--打开Activity次方法必然调用 


停止状态: 新应用完全覆盖,状态.信息等仍然保留.但用户不可见 触发onStop()-视应用是否可见来调用;onDestory(); 


关闭新的Activity重新触发onCreate();onstart();onresume()方法. 


  Android系统为了让程序再次启动的速度更快.程序并没有真正意义的关闭.而是存储在内存中 


内存管理机制: 


在内存不足时为了让系统决定杀死哪个进程,Android 根据每个进程中运行的组件以及组件的状态把进程放入一个“重要级别


(importance hierarchy)”中,级别低的进程优先被杀死。进程的重要级别排序(级别高的排在前面): 


1.前台(foreground)进程,与用户当前正在做的事情密切相关。当下面任何一个条件满足时,会考虑  将进程移到前台:  


进程正在屏幕的最前端运行一个与用户交互的Activity (它的onResume()方法被调用)  


进程有一正在运行的BroadcastReceiver (它的BroadcastReceiver.onReceive()方法正在执行)  


进程有一个Service,并且在Service的某个回调函数(Service.onCreate(), Service.onStart(), Service.onDestroy())内有正在执行的代码。  


 2.可见(visible)进程,它有一个可以被用户从屏幕上看到的Activity,但不在前台(它的onPause()方     法被调


用)。 


 3.服务(service)进程,进程中存在一个已经用startService()方法启动的Service。 


 4.后台(background)进程, 拥有一个当前用户看不到的Activity(它的onStop()方法被调用)。  


 5.空(empty)进程,不包含任何处于活动状态的应用程序组件。  


onSaveInstanceState() :当应用遇到意外情况由系统销毁一个Activity时会调用此方法来缓存一些数据 


onRestoreInstanceState() :调用此方法恢复缓存的数据, 


 重写onSaveInstanceState()和onRestoreInstanceState()方法 


    private String name; 


    protected void onRestoreInstanceState(Bundle savedInstanceState) { 


 name = savedInstanceState.getString("name"); //被重新创建后恢复缓存的数据  


 super.onRestoreInstanceState(savedInstanceState);    } 


    protected void onSaveInstanceState(Bundle outState) { 


 outState.putString("name", "liming");//被摧毁前缓存一些数据  


 super.onSaveInstanceState(outState);    } Bundle


类用作携带数据,它类似于Map,用于存放key-value名值对形式的值。相对于Map,它提供了各种常用类型的putXxx()/getXxx()


方法,如:putString()/getString()和putInt()/getInt(),putXxx()用于往Bundle对象放入数据,getXxx()方法用于从Bundle对象里获取数据。Bundle


的内部实际上是使用了HashMap<String, Object>类型的变量来存放putXxx()方法放入的值: 


public final class Bundle implements Parcelable, Cloneable { 


         Map<String, Object> mMap; 


 public Bundle() { 


       mMap = new HashMap<String, Object>();      } 


 public void putString(String key, String value) { 


      mMap.put(key, value); } 


public String getString(String key) { 


       Object o = mMap.get(key); 


        return (String) o; 


        ........//类型转换失败后会返回null,这里省略了类型转换失败后的处理代码}  } 


在调用Bundle对象的getXxx()方法时,方法内部会从该变量中获取数据,然后对数据进行类型转换,转换成什么类型由方法的Xxx决定,getXxx()方法会把转换后的值返回。 


请求码用于标识结果数据来自哪个startActivityForResult(Intent intent, int requestCode)方法 


结果码用于为结果数据定义唯一id 2.


 BroadcastReceiver(广播接收者): 


OnReceive()方法在10秒内没有执行,androidh会认为该程序无响应 


两种注册方式:代码注册,manifest中配置 


声明周期较短. 如有耗时的工作,应该通过发送Intent给Service.由Service来解决,不能让子线程解决 


短信窃听器: 继承BroadcastReceiver  intent的action名称为: android.provider.Telephony.SMS_RECEIVED  


获取信息内容: 


 Object[] pdus = (Object[]) intent.getExtras().get(“pdus”); 系统内部自动对pdus进行解析 


 循环迭代信息内容 


 For(Object[]  pdu : pdus) 


 格式转换”2011-01-01 12:00:00” 


 SimpleDateFormat  format =  new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”) 


 String time = format.format(date)   


拦截外拨电话: 


 获取拨打的号码  getResultData(); 


 将获取到得号码设置为null  setResultData(null);    


两种类型:: 粘性广播 


普通广播(Normal broadcasts), :接受者不能将处理结果传递给下一个接收者.并且无法终止广播Intent的广播 


有序广播(Ordered broadcasts):系统发出的广播为有序广播, 有序广播按照接受者声明的优先级别被接受者一次接收广播 


a.在<intent-filter android:priority=1000>属性中声明,数值越大优先级别越高,取值范围”-1000--1000” 


b调用intentFilter对象的Priority() 设置通过调用IntentFilter对象的setPriority()进行设置 


配置广播清单:在AndroidManifest.xml中  <application> 


<receiver anroid:name= “.SMSBroadcastReceiver”> 


<intent-filter> 


 <action android:name=”android.provider.Telephony.SMS_RECEIVED/> 


</intent-filter> 


</receiver> 


</application> 


abortBroadcast(); //终止广播传递 AIDL(android interface definition language) -


 


一种接口定义语言 约束两个进程间的通讯规则,供编译器生成代码,实现与两个进程之间的通信  文件后缀名为


 aidl   Interface IPersonService { 


        String sayHello(String name) 


}  android自动在gen目录下生产对应的java类 1.


接口名与aidl文件名相同 


2.接口和方法千不用加访问权限修饰符:public orivate ,protected等.也不能用final ,static  


3. Aidl默认支持类型包括java基本类型(int,long,boolean等)和(String,Llist,Map,CharSeqence),使用这些类型是不需要


import声明 ,对于list和map中的元素类型必须是Aidl支持的类型,如果使用自定义类型作为参数或返回值,自定


义类型必须实现Parcelable接口 4自定义类型和AIDL生成的其他接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中 


5 在aidl文件中所有非java基本数据类型参数必须加上in ,out inout标记.以指明参数是输入参数.输出参数还是输入


输出参数 


6 java原始类型默认的标记为in.不能为其他标记  3.Service(


服务):一个生命周期长并且没有用户界面的程序 


 在系统后台运行 


 onCreate(),只在服务创建时调用一次. 无论调用多少次startService()或bindservice().服务也只创建一次 


 启动方式: 


 Stratservice: 


 第一次启动at()onStartCommand() 


 启动后startCommand() 


Stopservice: 


Ondestroy(); 


服务与访问者在同一应用,仅供内部访问称为本地服务 ――内存交互 


 服务与访问者在不同应用.属于外部调用访问则为远程服务 -通过操作系统中介进行交互 


   继承Service类.android.app包   


  


startService()启动服务stopservice()关闭服务–适用于服务和访问者之间没有交互 


 在androidManifest.xml文件中<application>节点里对服务进行配置 


 媒体刻录机: MediaRecorder recorder = new MeidaRecorder(); 


 电话窃听器:  


 监听电话三种状态: 


 空闲状态: LISTEN_CALL_IDLE 


 响铃状态:LISTEN_STATE_RINGING 


 接听状态:LISTEN_STATE_OFFHOOK 


 注册监听器: 


  


 将录音文件保存在SDCARD根目录下   


<service  android:name read_phone_start>; 


将录音文件上传到服务器中: 


 


 bindService()启动服务 unbindService()关闭服务 –适用服务与访问者之间需要方法调用或者传递参数 


 IBinder:远程过程调用的核心部分 


 4.Content Provider


(内容提供者):实现程序与程序间的数据共享 


,需要在androidMainfest.XML声明 


<uses-permission android:name=”android:name=”android.permission.READ_CONTACTS”></uses-permission> 


 5.Intent(


意图):通过intent激活其他组建 三种核心组件,活动,广播接受者,服务 


1.用于返回新Activity结束后的结果数据: 


StartActivityForResult(intent,resultCode标识应用中的调用位置);  


2.重写 onActivityResult 方法 


protected void onActivityResult(int requestCode, int resultCode, Intent data)  用于往Activity传递数据 


 Activity1:   Intent.putExtre(“name”, “名称”);   //添加数据 


 Activity2:  intent.getintent(); String name = intent.getStringExtra(“name”);  //获取Activity1的数据 


显式意图:调用intent.setcomponet()intent.setclassName()或intent.setclass()方法明确指定了组件名 


隐式意图:根据设置的动作(action),类别(category),数据(URI和数据类型)找到合适的组件来处理 


  没有数据内容项的时候intent中的Action和category都必须出现在intentfileer中 


 隐式方法中设置的动作(action),类别(category),数据(URI和数据类型)必须与intent-filter 中的设置一致 <intent-filter> 


 <action android:name = “android.intent.action.CALL”/> 


 <categoy  android:name = ”android:intent.actionINTENT”/>  


 <data android:scheme=”” android:host:”主机名” android:path=”路径”/> 


 <data android:mimeType=”image/*”/> 


 SetType():会自动清除setData()所设置的数据,所以要用到setDataAndType(setData() , SetType()); 应用之间激活对方组件


 使用隐式  -性能比显式较低,内部有查找过程 


应用内部激活自身组件 使用显式 -  


startActivity(); --激活制定的Activity 


 在一个程序中添加多个Activity 


任务堆栈存放每个Activity实例的。当应用新打开时 ,入口activity会放在任务堆栈顶部,当在入口activity中激活了新的activity时,新


的activity实例会放在堆栈顶部 


默认行为:采用intent激活组建,会创建一个新的组件实例,放在堆栈顶部。 


修改需要在 AndroidManifest.xml 配置对应的 


android:launchMode=” standard-默认行为; 


singleTop-当Activity存在时,使用intent激活时重新调用该Activity; 


singleTask-打开Activity时会在新的堆栈中执行-新进程中运行; 


singleInstance-Activity在堆栈中存在时直接打开,永远保持一个Activity;”  


Application name: 应用的名称.默认出现在程序的图标的底下,标题栏.可以进行修改. 


Package: 包名为一标识一个应用.,一般存放java源文件. 


Greate Activity: 代表一个可以接收用户输入信息,事件的窗口. 


Min SDK Version:版本对应的级别. 


像素单位, 


px –,  dip || dp----常用像素密度使用 ,  sp, --文字使用 


<application android:icon="@drawable/应用图标名称" android:label="@string/app_name"> 


   


Android中数据采用URI表示 Setdata(Uri.parese(“”)); 


调用  StartActivity()  ;方法把意图传给操作系统. 激活对应的Activity 


<uses-permission android:name=”android.permission.INTERNET”/>访问网络权限设置 


权限:定义….summary类. 


   //方法的内部会自动为intent对象设置类别:android.intent.category.DEFAULT 


权限定义在XML文件<uses-permission android :name =”android.permission.CALL_PHONE”>; 


短信发送器: 


短信字符限制:70个汉字(包括标点),150个英文字母. 


短信拆分.------SmsMaager.getDefault(); 短信发送: 


SendTextMessage((destinationAddress)手机号, (scAddress)短信中心地址默认为null, 短信内容(text),(sentIntent)传一个广播意图,获取发


送短信后的状态默认为null,  (deliveryintent)得到发送短信后对方是否收到短信的状态默认为null) 


通知方式: 


Toast.makeText(context(上下文对象)类名.this或getapplicationcontext(),指定文字的自然ID text, dutation(toast在屏幕上显示的时间 Toast.0或


1)).show(); 


单元测试:  新建等待测试的业务类; 单元测试包跟应用包同名. 


单元测试类继承AndroidTestCase, 


 //定义一个TAG方法,进行测试; 


 private static final String TAG ="PersonServiceTest"; 


//方法名称必须加上test 


 public void testSave() throws Throwable{ 测试权限设置


: 在<application>节点下,放置单元测试库 <application> <uses-library android:name="android.test.runner"/> 


</application > 


<instrumentation android:name="android.test.InstrumentationTestRunner" 


  android:targetPackage="cn.test" android:label="Tests for My App" /> 


 结果检验..方法是否正常. 


Tag: 输出日志信息 


Log.v(TAG, "VERBOSE"); //verbose –所有信息 


        Log.d(TAG, "DEBUG");  //debug-除错 


        Log.i(TAG, "INFO");   //info-信息 


        Log.w(TAG, "WARN");  //warn-警告 


        Log.e(TAG, "ERROR");  //error-错误 


 ListVIew


控件


控件控件


控件:用于将各种控件


用于将各种控件用于将各种控件


用于将各种控件,数据显示到屏幕上


数据显示到屏幕上数据显示到屏幕上


数据显示到屏幕上  了解ListView的用法.如何将数据显示到屏幕上,添加点击事件进行操作 


 定义简单的适配器用来将绑定数据显示到ListView控件上:  1.Simpleadapter: 


用于得到给定数据索引位置的数据对象getitemAcposition(),内部使用get()方法取得数据的位置 


获取ListView中数据进行点击事件. 


通过调用数据的索引位置来进行点击事件 2.当业务bean返回类型为cursor类型时: 


业务bean中Cursor游标对象不能关闭,适配器对cursor对象进行迭代访问,关闭后无法得到数据 


表主键取名时 id 建议取名加 _id;否则会出错 


使用SimpleCursorAdapter  


 数据存储与访问


数据存储与访问数据存储与访问


数据存储与访问:  文件存储


文件存储文件存储


文件存储: 


保存的文件默认存放在/data/data/<package>/files 目录下 


Context.Openfileoutput(文件名称,文件的操作模式(Context.MODE_PRIVATE)私有操作模式只能在本应用操作文件,以覆盖方式写入数据);   //


创建一个文件.默认存放在手机存储空间 


4种文件操作方式: 1. context.MODE_PRIVATE:默认操作模式,只能被应用本身进行读取写入.以覆盖方式写入数据 


2. context.MODE_APPEND:文件存在则在文件末尾追加内容.否则创建新文件 


3. context.MODE_WORLD_READABLE:能被其他应用读取数据. 


4. context.MODE_WORLD_WRITEABLE:能被其他应用写入数据.不能被读取要追加内容需要改变路径保存方式(path, true()默认为false以覆


盖方式写入数据) getcacheDIr(); 


获取/data/data/<package name>/cache 目录---保存缓存 


getfileDir(); 获取/data/data/<package name>/file 目录---保存文件  (context.MODE_WORLD_READABLE+ context.MODE_WORLD_WRITEABLE); 


通过this.openfileputput(“…”,context.Mode_private)方法保存文件.文件将存储在默认目录下  


调用这个方法取得外存储设备的路径,应对不同版本的系统: 


Environment.getEcternalStorageDirectory() ,filename; 


首先判断SDcard是否存在 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) 


  File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录 <!-- 


在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  


Sharedpreferences配置参数保存


配置参数保存配置参数保存


配置参数保存:存放软件的配置参数 


 保存的文件默认存放在/data/data/<package>/shared_prets目录下 This.getSharedpreference(“??”, );--


追加方式存储数据 获取编辑框内容:edit.putString(“name”, name);   


    Edit.putInt(“age”,age); 


调用 edit.commit() ,回写到文件中 


数据默认保存在内存中 , 


 


SQLite数据库


数据库数据库


数据库: 


SQlite: 存储地址:/data/data/<package_name>/databases 


关系型数据库.支持5种据类型:NULL, NTEGER, EAL(浮点数字), EXT(字符串文本), LOB(二进制对象) 


无需加载数据库.自动加载驱动 


 存储字段无数据类型限制 可以保存任何类型数据. 


Super(content, “数据库名称”, 工厂方法.默认为null, 版本号:数据库第一次创建版本号为0 


.获取5条记录.跳过前面3条 Select*from Account limit 5 offset 3 继承


 SQLiteOpenHelper------- . 


通过getreadabledata (一般用于读取数据) 


或 .getwriteabledata (一般用于修改数据) 


创建数据库 


操作数据库使用openorcreateDatanase,存在则打开,不存在则创建,创建成功返回SQLiteDatabase对象 


创建表: 


CREATE TABLE person (personid integer primary key autoincrement, name varchar(20)); 查询表: private DBOpenHelper dbOpenHelper; 


  public PersonService(Context context){ 


  dbOpenHelper = new DBOpenHelper(context); 


 }  


 public void payment(){ 


  SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); 


  db.beginTransaction();  //开启事务 


  try{ 


   db.execSQL("update person set amount=amount-10 where personid=2"); 


   db.execSQL("update person set amount=amount+10 where personid=3"); 


   db.setTransactionSuccessful(); 


  }finally{ 


   //默认情况下,事务标志为False 


   db.endTransaction();//提交还是回滚,是由事务标志决定的,如果事务的标志为True,就会提交事务,否


则回滚事务 


  } }  


 public void save(Person person){ 


  SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); 


  db.execSQL("insert into person(name,phone,amount) values(?,?,?)", 


    new Object[]{person.getName(), person.getPhone(), person.getAmount()}); 


  //db.close(); 


 }  


 public void delete(Integer id){ 


  SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); 


  db.execSQL("delete from person where personid=?", new Object[]{id}); 


 }  


 public void update(Person person){ 


  SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); 


  db.execSQL("update person set name=?,phone=?,amount=? where personid=?", 


    new Object[]{person.getName(), person.getPhone(), person.getAmount(), person.getId()}); 


 } 


 public Person find(Integer id){ 


  SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); 


  Cursor cursor = db.rawQuery("select * from person where personid=?", new String[]{id.toString()}); 


  if(cursor.moveToFirst()){ 


   String name = cursor.getString(cursor.getColumnIndex("name")); 


   String phone = cursor.getString(cursor.getColumnIndex("phone")); 


   int amount = cursor.getInt(cursor.getColumnIndex("amount")); 


   cursor.close(); 


   return new Person(id, name, phone, amount);  } 


  return null; } 


  public List<Person> getScrollData(int offset, int maxResult){ 


  List<Person> persons = new ArrayList<Person>();   SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); 


  Cursor cursor = db.rawQuery("select * from person order by personid asc limit ?,?",  


    new String[]{String.valueOf(offset), String.valueOf(maxResult)}); 


  while(cursor.moveToNext()){ 


   Integer id = cursor.getInt(cursor.getColumnIndex("personid")); 


   String name = cursor.getString(cursor.getColumnIndex("name")); 


   String phone = cursor.getString(cursor.getColumnIndex("phone")); 


   int amount = cursor.getInt(cursor.getColumnIndex("amount")); 


   persons.add(new Person(id, name, phone, amount));  } 


  cursor.close(); 


  return persons; 


 }  


 public long getCount(){            


  SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); 


  Cursor cursor = db.rawQuery("select count(*) from person", null); 


  cursor.moveToFirst(); 


  long result =cursor.getLong(0); 


  cursor.close(); 


  return result; } } 通过


cursor对象对结果集进行随即访问.移动游标指针到指定位置  .rawQuery 


用Cursor类来实现;使用 SQLiteDataBase.query()返回cursor对象 


事务操作: beginTransaction()  //开启事务 


设置调用事务try{ setTransactionSuccessful()} 


finally{ EndTransaction()}//提交事务,默认为fals;如果事务的标志为True,就会提交事务,否则回滚事务} 


隔离级别:1,读未提交 2, 读已提交 4,可以重复读 8,串行化.悲观锁,不支持并发,安全性高,性能低 


网络


网络网络


网络(在互联网服务器中存储


在互联网服务器中存储在互联网服务器中存储


在互联网服务器中存储)Network: 


通过“GET” “POST”方法获取静态页面, 


1. 检测网络状态: ConnectivityManager cm = (ConnectivityManager) Context.getSystemService(Context.CONNECTIVITY_SERVICE); 


NetworkInfo netInfo = cm.getActiveNetworkInfo(); netInfo.toString(); 


2. 使用网络权限 <uses-permission android:name="android.permission.INTERNET"/> 


3. 通过URL+HttpURLConnection获得数据(文本和图片) 注:HttpUrlConnection中的is和os都是指body部分的数据. 


URL url = new URL("http://www.sohu.com"); 


HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 


conn.setConnectTimeout(5* 1000); //设置超时时间 


conn.setRequestMethod("GET");// 设置提交方法 


conn.getResponseCode() != 200) throw ..;  //响应码 


InputStream is = conn.getInputStream(); 


String result = readData(is, "GBK"); 


conn.disconnect(); 


//获取图片同上.  内容提供者


内容提供者内容提供者


内容提供者(Content Provider) 数据对外共享


数据对外共享数据对外共享


数据对外共享 


 统一数据的访问方式 


ContentProvider,可通过2种方法: 


1.创建一个属于你自己的ContentProvider 


2.将你的数据添加到一个已经存在的ContentProvider中,当然前提是有相同数 


据类型并且有写入 Content provider的权限。 


1.当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法: public class PersonContentProvider extends ContentProvider{ 


   public boolean onCreate() 


   public Uri insert(Uri uri, ContentValues values) 


   public int delete(Uri uri, String selection, String[] selectionArgs) 


   public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 


   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 


   public String getType(Uri uri)}  


通过contentresolver()取得共享数据 


2.第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , 


ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是


提供数据者),authorities 就是他的域名: <manifest .... > 


    <application android:icon="@drawable/icon" android:label="@string/app_name"> 


 <providerandroid:name=".类名"  android:authorities="给定的唯一标识cn.itcast.providers.personprovider"/> 


    </application> 


</manifest>  


Private Context  context; //声明一个上下文对象 


实现contentresolver接口  通过getcontentresolver()方法取得contentresolver对象 


Adapter()适配器:条目界面与数据的绑定 


内容观察者: 


 


XML解析:<元素节点>,<文本节点> 


1. DOM:基于XML文档树结构的解析,占用内存较高,适合随机访问XML文件(两次加载) 


Document object model 


2. SAX:基于事件流的解析方式.顺序访问xml文件内容,适合顺序访问,不可暂停或倒退,每一个文档,元素的开始或结束都会触发一个事


件.(一次加载) StartDocument  StartElement  endElement  endDocument character  获取


 


重写StartDocument  StartElement  endElement  endDocument character 方法 


3. PULL:基于XML节点内容对象,适合选择访问  Parser.next().获取下一个类型节点, 


XmlPullParser parser = new XmlPullParser(); 


解析XML文件类:XmlPullParser public class PullXMLReader { 


 


public static List<Person> readXML(InputStream inStream) { 


 XmlPullParser parser = Xml.newPullParser();  try { 


 parser.setInput(inStream, "UTF-8"); 


 int eventType = parser.getEventType(); 


 Person currentPerson = null; 


 List<Person> persons = null; 


 while (eventType != XmlPullParser.END_DOCUMENT) { 


  switch (eventType) { 


  case XmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理 


   persons = new ArrayList<Person>(); 


   break; 


  case XmlPullParser.START_TAG://开始元素事件 


   String name = parser.getName(); 


   if (name.equalsIgnoreCase("person")) { 


    currentPerson = new Person(); 


    currentPerson.setId(new Integer(parser.getAttributeValue(null, "id"))); 


   } else if (currentPerson != null) { 


    if (name.equalsIgnoreCase("name")) { 


     currentPerson.setName(parser.nextText());// 如果后面是Text节点,即返回它的值 


    } else if (name.equalsIgnoreCase("age")) { 


     currentPerson.setAge(new Short(parser.nextText()));    }   } 


   break; 


  case XmlPullParser.END_TAG://结束元素事件 


   if (parser.getName().equalsIgnoreCase("person") && currentPerson != null) { 


    persons.add(currentPerson); 


    currentPerson = null;   } 


   break;  } 


  eventType = parser.next(); } 


 inStream.close(); 


 return persons; 


 } catch (Exception e) { 


  e.printStackTrace();  } 


 return null; } } 生成


XML文件内容的序列化类: XmlSerializer    public static String writeXML(List<Person> persons, Writer writer){ 


    XmlSerializer serializer = Xml.newSerializer(); 


    try { 


        serializer.setOutput(writer);    


        serializer.startDocument("UTF-8", true); 


      //第一个参数为命名空间,如果不使用命名空间,可以设置为null 


        serializer.startTag("", "persons"); 


        for (Person person : persons){ 


            serializer.startTag("", "person"); 


            serializer.attribute("", "id", person.getId().toString()); 


            serializer.startTag("", "name");             serializer.text(person.getName()); 


            serializer.endTag("", "name"); 


            serializer.startTag("", "age"); 


            serializer.text(person.getAge().toString()); 


            serializer.endTag("", "age"); 


            serializer.endTag("", "person");        } 


        serializer.endTag("", "persons"); 


        serializer.endDocument(); 


        return writer.toString(); 


    } catch (Exception e) { 


        e.printStackTrace();    } 


    return null; } 多线程


多线程多线程


多线程: Handler: 线程处理器 负责将message和runable对象传递给messagequeue,并且在这些对象离开时,负责执行 


MessageQueue:消息队列   message列表的底层类。Looper负责分发这些message。Messages并不是 直接加到一个


MessageQueue中,而是通过MessageQueue.IdleHandler关联到Looper。 


Looper: 线程轮偱器Looper类被用来执行一个线程中的message循环。默认情况,没有一个消息循环关联到线程。在线程中调用prepare()


创建一个Looper,然后用loop()来处理messages,直到循环终止 


 动画


动画动画


动画: Tween: 


 Alpha:渐变透明度 


 Scale:渐变尺寸伸缩 


 Translate:画面转换位置移动 


 Rotate:画面转移旋转 


Frame动画 帧动画,类似于GIF动画,配置好每个图片,安装每一帧的顺序,出现时间进行更换 


显示:  


 /* 设置为无标题栏 */ 


  requestWindowFeature(Window.FEATURE_NO_TITLE);  


 /* 设置为全屏模式 */  


getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  


 /* 设置为横屏 */ 


  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);; 多媒体


多媒体多媒体


多媒体: Open Core(PV,Packet Video): 多媒体框架的核心 


 PVPlayer:媒体播放器—音频(Audio),视频(Video)流的回放 


 PVAuthor:媒体流记录—音频,视频流以及静态图像的捕获 


getDuration() 获取播放文件总时间 


音乐播放器: 


音乐文件播放由MeidaPlayer 内部调用底层代码进行运行 MediaPlayer mediaPlayer = new MediaPlayer(); 


if (mediaPlayer.isPlaying()) { 


   mediaPlayer.reset();//重置为初始状态 


} mediaPlayer.setDataSource("/mnt/sdcard/god.mp3"); 


mediaPlayer.prepare();     


mediaPlayer.start();//开始或恢复播放 


mediaPlayer.pause();//暂停播放 


定义一个变量,记录播放位置 


mediaPlayer.start();//恢复播放 


mediaPlayer.stop();//停止播放 


mediaPlayer.release();//释放资源 


mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {//播出完毕事件 


        @Override public void onCompletion(MediaPlayer arg0) { 


     mediaPlayer.release();        } 


}); 


mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {// 错误处理事件 


         @Override public boolean onError(MediaPlayer player, int arg1, int arg2) { 


 mediaPlayer.release(); 


 return false;     } }); 


setVisibility 


//绑定拖动条-获取媒体的长度 


    private void refreshSeekbar() { 


  Runnable r = new Runnable() { 


   public void run() { 


    if(player.isPlaying()){ 


     int currPos = player.getCurrentPosition(); 


     bar.setProgress(currPos); 


     h.postDelayed(this, 500); 


    }   }  }; 


  //清除队列中r消息. 


  h.removeCallbacks(r); 


  //发送r对象到消息队列 


  h.post(r); } 视频播放器





 当SurfaceView所在的Activity不在前台,SurfaceView会被销毁,如果Activity重新回到前台SurfaceView会被重新创建,但SurfaceView创建的


时间会在OnResunme()方法之后., 


 需要创建回调监听时间. 模拟器2.1以上版本不能正常播放视频文件  SurfaceView –


表层视图 绘图界面 .显示视频界面 


surfaceView.getHolder() –获取控制对象,以显示内容-进行图画操作 


在main.xml布局文件添加用于视频画面绘制的SurfaceView 控件: 


<SurfaceView android:layout_width="fill_parent" android:layout_height="240dip"android:id="@+id/surfaceView" /> 


SurfaceView surfaceView = (SurfaceView)this.findViewById(R.id.surfaceView); 


surfaceView.getHolder().setFixedSize(176, 144); //设置分辨率 


/*下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前*/ 


surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 


MediaPlayer mediaPlayer = new MediaPlayer(); 


mediaPlayer.reset();//重置为初始状态 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 


/* 设置Video影片以SurfaceHolder播放 */ 


mediaPlayer.setDisplay(surfaceView.getHolder()); 


mediaPlayer.setDataSource("/mnt/sdcard/oppo.mp4"); 


mediaPlayer.prepare();     


mediaPlayer.start();//播放 


mediaPlayer.pause();//暂停播放 


mediaPlayer.start();//恢复播放 


mediaPlayer.stop();//停止播放 


mediaPlayer.release();//释放 


在线视频播放:  


流媒体两种分发方式: 


 渐进式下载(Progressive Download) :可以通过HTTP或FTP协议来分发,需要Web服务器或者FTP服务器 


 需要将视频文件转换为渐进式视频文件-3G格式 


 实时流媒体: 通过RTP和RTSP这种实时协议来分发,那样的话就需要一个流媒体服务器 


 网络通信


网络通信网络通信


网络通信: 


 HTTP通信


通信通信


通信: 


”一次连接


一次连接一次连接


一次连接” 连接过程


连接过程连接过程


连接过程:客户端


客户端客户端


客户端->发送请求


发送请求发送请求


发送请求->服务器回送响应


服务器回送响应服务器回送响应


服务器回送响应->释放连接


释放连接释放连接


释放连接 3


种网络接口: 


java.net*(标准java接口), 提供与联网有关的类,包括流和数据包套接字,Internet协议,常见HTTP处理 


orgapache(Apache接口), HTTPClient 更加完善的HTTP扩展开源项目 


android.net*(Android网络接口) 


 


HttpClient接口: 使用HttpClient上传文件缓存超过1M会出现内存溢出 


1. clientConnectionManager接口:客户端连接管理器接口,提供几个抽象方法: 


clientconnectionManager-关闭所有无效


关闭所有无效关闭所有无效


关闭所有无效,超时的连接


超时的连接超时的连接


超时的连接 


chosedleConnections- 关闭空闲的连接


关闭空闲的连接关闭空闲的连接


关闭空闲的连接 


releaseconnection-释放一个连接


释放一个连接释放一个连接


释放一个连接 


requestConnection-请求一个新的连接


请求一个新的连接请求一个新的连接


请求一个新的连接 


shutdown-关闭管理器并释放资源


关闭管理器并释放资源关闭管理器并释放资源


关闭管理器并释放资源 


2. defaultHttpClient: 默认的一个HTTP客户端,可以使用创建一个HTTP连接: 


例子:HttpClient httoclient= new DefaultHttpClient(); 


3. HttpResphone: 是一个Http连接响应,当执行一个HTTP连接后,就会返回一个HttpResponse,可以通过HttpResphonse获得一些响应


信息, 请求HTTP连接并获得请求是否成功的代码: 


HttpResponse httpResponse= httpclient.execute(httpRequest); 


If(httpResponse,getStatusLine().getStatusCode()== HttpStatus.SC_OK){ 


 //连接成功 





 Socket


通信


通信通信


通信: 


 用于描述


IP地址和端口,是一个通信链的句柄 


 包含进行网络通信必须得5种信息:  


 1.连接使用的协议, 2.本地主机的IP地址, 3.本地进程的协议端口, 


 4.远地主机的IP地址, 5.远地进程的协议端口  两种主要的操作方式: 面向连接和无连接  


 Webservice:  


调用API.用于对各个独立的应用程序之间进行串联调用www.webxml.com.cn 


Soapaction-请求头soap有.1.2没.1.2加上会报错 


公开在网络上的API,通过soap协议调用(基于XML语法) 


   wsdl


:用于查看描述接口语言  使用webservice调用手机归属地API进行归属地查询: 


 /*@param mobile 


手机号*/ 


 public static String getAddress(String mobile) throws Exception{ 


  InputStream inStream = MobileService.class.getClassLoader().getResourceAsStream("soap12.xml"); 


  byte[] data = StreamTool.read(inStream); 


  String xml = new String(data); 


  xml = xml.replaceAll("\\$mobile", mobile); 


  data = xml.getBytes(); 


  String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"; 


  HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection(); 


  conn.setConnectTimeout(5000); 


  conn.setRequestMethod("POST"); 


  conn.setDoOutput(true); 


  conn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");//soap格式数据 


  conn.setRequestProperty("Content-Length", String.valueOf(data.length)); 


  conn.getOutputStream().write(data);   


  if(conn.getResponseCode() == 200){ 


   InputStream soapStream = conn.getInputStream(); 


   return parseXML(soapStream);  }   


  return null; }   * 


解析soap协议,得到返回结果 


  private static String parseXML(InputStream soapStream) throws Exception{ 


  XmlPullParser pullParser = Xml.newPullParser(); 


  pullParser.setInput(soapStream, "UTF-8"); 


  int event = pullParser.getEventType(); 


  while(event!= XmlPullParser.END_DOCUMENT){ 


   switch (event) { 


   case XmlPullParser.START_TAG: 


    if("getMobileCodeInfoResult".equals(pullParser.getName())){ 


     return pullParser.nextText();    } 


    break;   } 


   event = pullParser.next();  } 


  return null; } } 


//调用手机归属地的SOAP协议 


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


<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  


xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">   <soap12:Body> 


    <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> 


      <mobileCode>$mobile</mobileCode> 


      <userID> </userID> 


    </getMobileCodeInfo> 


  </soap12:Body> 


</soap12:Envelope> 


  手势识别


手势识别手势识别


手势识别:    第一步:建立手势库 


使用SDK自带例子GestureBuilder建立手势库(位置:android-sdk-windows\samples\android-8\GestureBuilder


)。使用


 GestureBuilder之前,你需要恢复其到开发环境,然后进行编绎并部署到手机上。此时,就可以使用GestureBuilder建立手势库,生成


的手势库文件在SCDard上,默认文件名称为:gestures 


第二步:在应用中加载手势库文件,然后开发手势识别代码。 


把手势库文件gestures文件拷贝到项目的res/raw目录下。然后在布局文件中添加用于手势绘制的View:  <android.gesture.GestureOverlayView  


    android:id="@+id/gestures" 


    android:layout_width="fill_parent“ android:layout_height="0dip" 


    android:layout_weight="1.0" /> 为


View添加手势监听事件:gestureOverlayView.addOnGesturePerformedListener(); 


 监听单笔事件overlayView.addOnGesturePerformedListener(new GestureListener());  监听多笔事件:overlayView.addOnGrestureListener(new GestureListener()); 得到手势库:mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);  加载手势库:mLibrary.load();List<Prediction> predictions = mLibrary.recognize(gesture); 


//从手势库中查询匹配的内容,匹配的结果可能包括多个相似的内容,匹配度高的结果放在最前面  


大多数情况下,手势都是通过一笔完成。然而有一些特别的需求就需要通过多个笔画来实现,这时可以使多笔手势: 用


gestureStrokeType属性进行设置:android:gestureStrokeType="multiple"  


应用关闭:2.2之前版本 


 1.获取当前进程ID,杀死进程(建议使用) 


 Android.os.Proicess.killProcess(android.os.Process.myPid())  2.


终止当前正在运行的java虚拟机,导致程序终止 


 System.exit(0);  3.


强制关闭与该包有关联的一切执行 


 ActiviryManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 


 Manager.restartPackage(getPackageName()); 


 <uses-permission android:name=”android:permission.RESTART_PACKAGES”/>  Widget:(


窗口小部件)     <metea-data>: 


 每个widget就是一个BroadcastReceiver(广播接受者) 


 使用XML metadata来描述Widget细节  WebKit


应用:    开源的浏览器网页排版引擎 


 对应:Geko(Mozilla,Firefox等使用)  Trident(也称MSHTML,IE使用)  可以运行HTML代码 可以与Javascript 互相调用 


 由3个模块组成: 


 JavaSciptCore: WebCore: WebKit 


 使用:在XML布局文件中定义webView控件: 


  <WebView 


android:id =”+id/WebVIew” 


android=layout_width=”fill_parent” 


android=layout_heigth=”fill_parent” 


android:layout_weigth=”1”/> 


国际化


国际化国际化


国际化: 文字


,.图片.屏幕适配,样式,主题 


控件: 


 话框通知


(Dialog Notification): 


当你的应用需要显示一个进度条或需要用户对信息进行确认时,可以使用对话框来完成。  


下面代码将打开一个如右图所示的对话框:  


new AlertDialog.Builder(context) 


 .setTitle("java培训") 


 .setCancelable(false) //设置不能通过“后退”按钮关闭对话框  


 .setMessage("浏览传智播客网站?") 


 .setPositiveButton("确认", 


  new DialogInterface.OnClickListener(){ 


  public void onClick(DialogInterface dialoginterface, int i){ 


          Uri uri = Uri.parse("http://www.itcast.cn/");//打开链接 


          Intent intent = new Intent(Intent.ACTION_VIEW, uri); 


          startActivity(intent);    } }) 


 .setNegativeButton("取消", new DialogInterface.OnClickListener() { 


             public void onClick(DialogInterface dialog, int id) { 


                   dialog.cancel();       }     }) 


     .show();//显示对话框  


上面代码采用的是一个链式调用,像setTitle()、setMessage()这些方法,他们的返回值都是当前对话框对象。  


创建带单选项列表的对话框: 下面代码将打开一个如右上图所示的选项列表对话框:


  final String[] items = {"java", ".net", "php"}; 


new AlertDialog.Builder(SenderNotificationActivity.this).setTitle("选择语言") 


 .setItems(items, new DialogInterface.OnClickListener() { 


     public void onClick(DialogInterface dialog, int item) { 


             Toast.makeText(getApplicationContext(), items[item],  


  Toast.LENGTH_SHORT).show(); 


     } 


 }).show();//显示对话框  下面代码将打开一个如右下图所示的带单选框的列表对话框:


  final String[] items = {"java", ".net", "php"}; 


new AlertDialog.Builder(SenderNotificationActivity.this).setTitle("选择语言") 


.setSingleChoiceItems(items, 1, new DialogInterface.OnClickListener() {   public void onClick(DialogInterface dialog, int item) { 


         Toast.makeText(getApplicationContext(), items[item],  


  Toast.LENGTH_SHORT).show(); 


         dialog.cancel();   } 


}).show();//显示对话框  setSingleChoiceItems()


的第二个参数是设置默认选项,  


选项索引从0开始,-1代表不选择任何选项。  创建带多选项列表的对话框


:  下面代码将打开一个如右下图所示的多选项列表对话框: final String[] items = {"java", ".net", "php"}; 


new AlertDialog.Builder(SenderNotificationActivity.this).setCancelable(false) 


.setTitle("选择语言") 


.setMultiChoiceItems(items, new boolean[]{false,true,false}, new DialogInterface.OnMultiChoiceClickListener() { 


 @Override 


 public void onClick(DialogInterface dialog, int which, boolean isChecked) { 


  if(isChecked){ 


  Toast.makeText(getApplicationContext(), items[which],  


   Toast.LENGTH_SHORT).show();  }  } }) 


.setPositiveButton("确认", 


 new DialogInterface.OnClickListener(){ 


 public void onClick(DialogInterface dialoginterface, int i){ 


  dialoginterface.dismiss();  }}) 


.show();//显示对话框  进度对话框


(ProgressDialog) 使用代码ProgressDialog.show(ProgressDialogActivity.this, "请稍等", "数据正在加载中...", true);创建并显示一个进度对话框。 


调用setProgressStyle()方法设置进度对话框风格。有两种风格: 


     ProgressDialog.STYLE_SPINNER 旋体进度条风格 (为默认风格) 


     ProgressDialog.STYLE_HORIZONTAL 横向进度条风格 


 单选框(RadioButton) 


 完成单选框显示,我们需要使用到RadioGroup和RadioButton(单选框),RadioGroup用于对单选框进行分组,相同组内的单选框只有


一个单选框能被选中。(例子代码请见下方备注栏) 


 RadioGroup.check(R.id.dotNet);将id名为dotNet的单选框设置成选中状态。 


(RadioButton) findViewById(radioGroup.getCheckedRadioButtonId());//获取被选中的单选框。 


RadioButton.getText();//获取单选框的值 


调用setOnCheckedChangeListener()方法,处理单选框被选择事件,把RadioGroup.OnCheckedChangeListener实例作为参数传入 


 多选框


(CheckBox) 每个多选框都是独立的,可以通过迭代所有多选框,然后根据其状态是否被选中再获取其值。 


 CheckBox.setChecked(true);//设置成选中状态。 


 CheckBox.getText();//获取多选框的值 


 调用setOnCheckedChangeListener()方法,处理多选框被选择事件,把CompoundButton.OnCheckedChangeListener实例作为参数传入 


 下拉列表框


(Spinner) 


Spinner.getItemAtPosition(Spinner.getSelectedItemPosition());获取下拉列表框的值 


 调用setOnItemSelectedListener()方法,处理下拉列表框被选择事件,把AdapterView.OnItemSelectedListener实例作为


参数传入  下拉列表框—采用javabean作为Adapter元素 很多时候显示在下拉列表框的值并不是希望得到的值,如果要做一个联系人下拉列表框,列表框列出的是联系人的姓名,因为姓名有可能


相同,所以我们希望得到的值应该为该联系人的id,要实现这种需求我们需要自定义Adapter,当然自定义Adapter需要我们编写一小段代


码,如果我们不想编写Adapter,又能实现我们的需求,那是最好不过的了。通过观察ArrayAdapter中getView(int position, View convertView, 


ViewGroup parent)的内部代码发现,如果为ArrayAdapter指定的实际泛型参数类型没有实现CharSequence(字符串)接口,将会调用该类


型对象的toString()向下拉列表框输出显示值。利用这个特点我们可以重写javaBean的toString()向下拉列表框提供显示值。 


 下拉列表框


--自定义选项界面样式 


Spinner.getItemAtPosition(Spinner.getSelectedItemPosition());获取下拉列表框的值 


 调用setOnItemSelectedListener()方法,处理下拉列表框被选择事件,把AdapterView.OnItemSelectedListener实例作为


参数传入 


 拖动条(SeekBar) 


SeekBar.getProgress()获取拖动条当前值 


 调用setOnSeekBarChangeListener()方法,处理拖动条值变化事件,把SeekBar.OnSeekBarChangeListener实例作为参数


传入 


 菜单(Menu) 重写


Activity的onCreateOptionsMenu(Menu menu)方法,该方法用于创建选项菜单,在用户按下手机的“Menu”按钮时就会显示创


建好的菜单,在onCreateOptionsMenu(Menu menu)方法内部可以调用


Menu.add()方法实现菜单的添加。 


重写Activity的onMenuItemSelected()方法,该方法用于处理菜单被选择事件


 


 进度条


(ProgressBar) 在布局xml文件中添加进度条代码: <ProgressBar  


    android:layout_width="fill_parent"  


    android:layout_height="20px" 


    style="?android:attr/progressBarStyleHorizontal" 


    android:id="@+id/downloadbar"/>  在代码中操作进度条:


 ProgressBar.setMax(100);//设置最大刻度 ProgressBar.setProgress(0);//设置进度条的当前刻度,如果进度条的最大刻度为100,当前刻度为50,进度条将进行到一半。 


通过手机上提供的“MENU”按钮可以打开菜单,如果希望通过代码打开菜单,可以调用Activity的openOptionsMenu()方法。


 


 输入内容自动完成文本框(


AutoCompleteTextView ) AutoCompleteTextView和EditText组件类似,都可以输入文本。 


但AutoCompleteTextView组件可以和一个字符串数组或List对象 


绑定,当用户输入两个及以上字符时,系统将在 


AutoCompleteTextView组件下方列出字符串数组中所有以输入 


字符开头的字符串,这一点和www.google.com的搜索框非常相似, 


当输入某一个要查找的字符串时,google搜索框就会列出以这个 


字符串开头的最热门的搜索字符串列表。 <AutoCompleteTextView 


   android:layout_width="fill_parent“  android:layout_height="wrap_content“ 


  <!– completionThreshold 指定至少输入几个字符后才会出现自动提示功能 ? 


   android:completionThreshold="1“   


   android:id="@+id/name" /> 


public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState); 


 setContentView(R.layout.main);  String[] names = {"老张", "老方", "老毕", "李明" , "李丽", "陈江", "abc", "acc"}; 


 AutoCompleteTextView nameText = (AutoCompleteTextView)this.findViewById(R.id.name); 


 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, names); 


 nameText.setAdapter(adapter); 


 多次输入-内容自动完成文本框(MultiAutoCompleteTextView) 除了


AutoCompleteTextView控件外,我们还可以使用MultiAutoCompleteTextView控件来完成连续输入的功能。也就是说,当输入完一个字


符串后,在该字符串后面输入一个逗号(,),在逗号前后可以有任意多个空格,然后再输入一个字符串,仍然会显示自动提示列表。 


使用MultiAutoCompleteTextView时,需要为它的setTokenizer方法指定


MultiAutoCompleteTextView.CommaTokenizer类对象实例, 


该对象表示采用逗号作为输入多个字符串的分隔符。 nameText.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); 定义相应的文件夹





 判定SIM运营商 


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


TelephonyManager telManager = (TelephonyManager)  


   getSystemService(Context.TELEPHONY_SERVICE); 


 //移动(46000,46002),联通(46001),电信(46003) 


String imsi = telManager.getSubscriberId(); 


imsi.startsWith("46002") 


String operator = telManager.getSimOperator(); 


operator.equals("46000"); 


Line1Number:手机号 


NetworkOperatorName:网络运行商名称 


SimSerialNumber:Sim卡序列号 


 提取SIM联系人 


 Uri uri = Uri.parse("content://icc/adn"); 


String[] projection = {"_id", "name", "number"}; 


Cursor cursor = managedQuery(uri, projection, null, null, "name"); 


if(cursor!=null){ 


while(cursor.moveToNext()){ 


 String name = cursor.getString(cursor.getColumnIndex("name")); 


 String phone = cursor.getString(cursor.getColumnIndex("number")); } } 


在文件AndroidManifest.xml中添加权限 


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


Android系统内部通过Contentprovider对外共享Sim卡存放的联系人等信息,你可以通过 


操作Contentprovider来实现Sim卡信息的添删改查操作. 


 删除呼叫记录 


 在文件AndroidManifest.xml中添加权限 


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


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


负责存放呼叫记录的内容提供者源码在ContactsProvider项目下: 


源码路径: 


com\android\providers\contacts\CallLogProvider.java 


CallLog.Calls.URI: 


使用到的数据库在: /data/data/com.android.providers.contacts/databases/contacts2.db 


表名:calls 


呼叫记录有三种类型: 


来电:CallLog.Calls.INCOMING_TYPE(常量值:1) 


外拔:CallLog.Calls.OUTGOING_TYPE(常量值:2) 


未接:CallLog.Calls.MISSED_TYPE(常量值:3) 


 使用ndk开发android程序(本地文件开发包) 


 NDK不是替换掉SDK,而是增强他们,不能使用NDK创建独立的应用程序,NDK编译C的代码到类库中供java程 


序调用,NDK处理打包过程,确保APK文件既包含java代码又包含类库. 


 绝大多数程序不需要考虑NDK开发,但如果执行大量按位运算,像原始信号转换,图像压缩,加密比较适合NDK开发, 


NDK具有高效的内存使用和快捷的原始数据处理.通过c访问openGL库也能够得到更好的性能. 


除了以上的情况外,许多linux程序是c编程实现,使用NDK可以对遗留的程序进行重用. 


 NDK编写的代码不保证在同样算法条件下比java代码执行更快,NDK不应被视为提升程序性能的自动选择,NDK是 


问题复杂化,应全面考虑后再使用.NDK适合于自包含和CPU敏感型操作.这样,内存分配可保持在最小的状态. 


查看NDK 


1.下载ndk [http://developer.android.com/sdk/ndk] 


 查看${NDK解压目录}/toolchains\arm-linux-androideabi-4.4.3\prebuilt\windows\bin\ 


2.使用NDK开发步骤 


 创建android项目 


 创建类库源文件夹 


 创建c源文件 


 创建Android.mk文件 


 改变目录到源文件夹,之心NDK命令 


 执行NDK到项目build中(可选) 


 查看任何编译/链接错误. 


注:  文档中的案例在linux环境下运行的,在windows下不能执行ndk命令,需要单独下载cygwin才可以. 


${ndk解压目录}/doc/INSTALL.html 


 windows需要安装Cygwin1.7. 


ndk构建项目参考doc-->sdk-->android ndk1.4-->Getting Started with the NDK. 


 1.${project}/jni/c代码 


 2.创建${project}/jni/Android.mk文件 


 3.创建${project}/jni/Applicaiton.mk文件(可选) 


 4.在${project}目录下运行ndk-build脚本build本地代码.位于项目的定级目录 


  $ cd <project> 


  $ <ndk>/ndk-build 


 注: windows下需要进入到Cygwin.exe中进行ndk-build命令的执行 


 1.开始-->Cygwin 


 2.cd D:\eclipse-xxx\..\lsn_hellojni 


 3.d:\android-ndk-r6\ndk-build 


 4.完成 


 5.ide中刷新android项目 


 6.自动生成libs + obj文件夹,并生成so类库文件 


 7.运行.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值