移动开发

目录 html

1、构建Android开发环境... 4 java

1.用eclipse作Android的开发... 4 android

2.用手机作虚拟设备... 4 sql

2、生命周期... 4 shell

1.用于调度和控制的事件回调函数... 4 数据库

2.参考的调用顺序... 5 api

3.软件测试方法... 5 数组

(1)日志点... 5 多线程

(2)应用程序提示... 6 oracle

(3)DevTools 6

3、用户界面UI 6

1.MVC模型... 6

2.界面控件... 6

(1)显示和编辑字符的控件... 6

(2)按钮控件... 6

(3)提供选择的控件... 7

(4)微调选框... 7

(5)垂直显示的列表控件... 7

(6)设置监听器... 8

3.界面布局... 8

(1)线性布局... 8

(2)相对布局... 8

(3)网格布局... 8

(4)表格布局... 8

(5)绝对布局... 8

(6)帧布局... 8

4.菜单(操做栏,由菜单组成)... 8

(1)菜单资源... 8

(2)快捷菜单... 9

5.Fragment可重用模块... 9

(1)Fragment生命中的事件回调函数... 9

(2)使用方法... 10

6.事件监听... 10

(1)键盘事件setOnKeyListener 10

(2)触摸事件setOnTouchListener 10

4、组件通讯与广播... 10

1.Intent 10

2.Intent过滤器... 11

2.广播... 12

(1)发出信号... 12

(2)接收信号... 12

5、后台服务... 13

1.java和CC++易混淆的语法... 13

2.Service的生命周期... 13

3.本地服务... 13

(1)显式使用Service. 13

(2)隐式使用Service. 13

4.多线程... 14

5.绑定服务... 16

6.自定义数据的传输... 20

6、数据存储与访问... 22

1.SharedPreferences 22

2.文件存储... 23

(1)打开文件准备写数据... 23

(2)写文件... 23

(3)打开文件准备读数据... 24

3.外部存储... 24

(1)写数据... 24

(2)读数据... 25

4.资源文件... 26

(1)读取原始文件... 26

(2)读取二级xml文件,好比... 26

5. 数据库存储... 28

(1)手工建库... 28

(2)代码建库... 28

6.ContentProvider 29

(1)将数据项进行封装... 29

(2)继承ContentProvider并重载其中的方法... 29

(3)AndroidManifest.xml中注册ContentProvider 29

(4)其余应用和共享数据库的交互... 29

7、位置和地图... 29

8、Widget组件开发... 29

9、Android NDK.. 29

10、特效... 29

1.tab标签页... 29

11、附录... 30

1.参考网址... 30

2.eclipse快捷键... 30

3.adb命令... 30

4.avd命令... 31

5.模拟器设置中文... 31

正文

1、构建Android开发环境

1.用eclipse作Android的开发

(1) 下载JDK的可执行文件并执行

(2) 下载adt的zip压缩包

(3) 下载较新的SDK并解压SDK

(4) 下载eclipse并运行,选择help->install new software->add->archive->下载完毕的adt压缩文件

(5) 去掉“contact all update sites during install to find required software”选项,提升安装速度

(6) 重启eclipse后选择SDK解压后的位置

(7) Windows系统利用上vt技术的话,AVD的反应速度要快不少:启动BOIS启动vt,在sdk\extras\intel\Hardware_Accelerated_Execution_Manager下安装intel加速器,在此基础上创建一个intel驱动的AVD并启动

(8) 建立新项目

2.用手机作虚拟设备

下面用的是SUMSUNG手机,这种办法只能看到当前应用的信息

(1)About phone->Software information

(2)连续点击Build number3次

(3)在Developer options中打开USB debugging,并选择适当设置

(4)用USB链接手机,就能够经过IDE选择这个手机作模拟设备,运行须要调试的应用

2、生命周期

程序在Android系统中从启动到终止的全部过程,程序不能控制自身的生命周期而受系统的调度和控制。

1.用于调度和控制的事件回调函数

onSaveInstanceStae()用于保存activity界面的临时信息、信息通常放在Bundle中,onRestoreInstanceState()用于程序被销毁时恢复临时信息、好比程序遇到锁屏或者被系统中断,可是它们都不是生命周期的时间回调函数。

onCreate()

用于activity的初始化、建立链接、绑定数据等,是第一个被调用的函数

onStart()

activity显示在屏幕上时被调用

onRestart()

activity从新启动时调用、以后调用onResume()继续和用户交互

onResume()

获取屏幕焦点、接收用户输入时被调用

onPause()

程序被其余窗口覆盖,系统调用函数“暂停”程序、以后调用onSaveInstanceStae()保存临时信息

onStop()

用户不可见时,进入中止对activity更新

onDestroy()

程序调用finish()函数或者被系统终结的时候调用

2.参考的调用顺序

当用户离开当前页面又从新回到这个页面时,会调用onStart()、onStop()

clip_image001clip_image002

3.软件测试方法

(1)日志点

好比Log.i(String TAG,String cnt);,还能够选.w、.e等不一样的日志信息等级,查看日志的方法是在Logcat中创建过滤器,输入Filter Name、Tag的内容(即字符串TAG),选择日志的级别肯定便可。

(2)应用程序提示

好比Toast.makeText(MainActivity.this, "服务未绑定", Toast.LENGTH_SHORT).show();

(3)DevTools

做为前两种办法的补充,若是前面的办法还不能分析出错误缘由,再考虑DevTools提供的信息。

3、用户界面UI

1.MVC模型

模型、视图、控制器,控制器加工用户输入的数据、交给处理核心“模型”,最终由“模型”来更新视图。

2.界面控件

用eclipse的layout设计界面制做静态的UI,用java控制动态的内容、先声明一个控件变量而后用findViewById引用xml中的资源进行初始化。具体的函数能够查阅android的API文档。

控件的属性在设计界面中有,也能够查阅android的手册。

(1)显示和编辑字符的控件

TextView

设计界面中双击控件,能够进入控件的xml文件

<TextView android:id=”@+id/TextView0”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”TextView0”/>

EditText经常使用函数

getText().toString()

获取文本内容

setText()

设置文本内容

selectAll()

选中所有

findFocus()

获取输入的焦点

(2)按钮控件

Button、ImageButton

(3)提供选择的控件

CheckBox用于多选、RadioGroup和RadioButton用于单选。

经常使用函数

isChecked()

控件是否被选中

   
   
(4)微调选框

Spinner是一个相似下拉列表的东西,由于可能有不一样的选项、存在动态的内容,须要java写适配器将要显示的内容和底层的数据统一块儿来。一个可行的例子是:

//spinner初始化

spinner = (Spinner) findViewById(R.id.spinner1);

//要显示的数据

List<String> li=new ArrayList<String>();

li.add("cnt0");

li.add("cnt1");

li.add("cnt2");

li.add("cnt3");

//适配器初始化

ArrayAdapter<String> ad=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,li);

//适配器样式

ad.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

//给spinner设置适配器ad

spinner.setAdapter(ad);

(5)垂直显示的列表控件

ListView中若是内容不少,就会出现滚动条;若是没有内容,将不显示控件。

(6)设置监听器

监听器属于控件的方法,将使用内部类、若是出现错误多是没有加上View.,在android_api.chm中也有具体的说明。好比OnClickListener、

① 控件独占一个监听器

好比列表控件中给每一个子项设置监听器,listView.setOnItemClickListener(new AdapterView.OnIOnItemClickListener(){…});

② 多个控件共享一个监听器

方法是定义一个监听器,而后用v.getId()区分各个控件写上须要的代码,最后控件绑定这个监听器。若是一种类型的控件屡次出现,尽可能用这种方法设置监听器,消除一些没必要要的冗余,。

3.界面布局

布局之间能够相互嵌套,按经常使用的程度分为:

(1)线性布局

LinearLayout能够选择水平也能够选择垂直,还能够像html中table的行列组合使用、这样就灵活多了。

(2)相对布局

RelativeLayout使用相对的位置以适应不一样的屏幕尺寸,灵活并且比较稳定。

(3)网格布局

和表格布局相似,可是网格布局中的元素能够占用多个网格,而表格布局中的元素不能跨行跨列。

(4)表格布局

TableLayout默认控件独占一行,TableRow默认控件尽可能放在一行。

(5)绝对布局

在layout设计界面中已经找不到,可是在手动建立布局的xml文件的时候有这样一种布局,部件的位置像坐标同样严格的受到数值的控制、不一样的设备上效果不必定好。

(6)帧布局

一种相似坐标的自由布局FrameLayout

4.菜单(操做栏,由菜单组成)

能够在onCreate函数中用getActionBar().hide();隐藏操做栏的菜单,也能够经过修改app的主题styles作到一样的效果

(1)菜单资源

在menu目录中用layout设计菜单、onCreateOptionsMenu函数中用getMenuInflater().inflate方法映射成Menu对象,以后在onOptionsItemSelected函数中写入动态交互的内容便可;也能够用纯代码的方式实现,好比:

一级菜单

menu.add(0, menu0, 0, "打印").setIcon(R.drawable.ic_launcher);

多级菜单

menu.addSubMenu(0, menu0, 0, "新建").setIcon(R.drawable.ic_launcher);

说明:menu0是int对象要提早用Menu.FIRST初始化

(2)快捷菜单

具备快捷菜单的元素,若是按住它超过两秒,就会启动它的快捷菜单;和菜单资源相似,不一样的是须要重载onCreateContextMenu函数,最后对须要的元素注册快捷菜单,方法是registerForContextMenu。

5.Fragment可重用模块

把页面中可能重复使用的部分作成Fragment,在一个activity中调用、提升了代码的可重用性。

(1)Fragment生命中的事件回调函数

clip_image003

(2)使用方法

① layout设计界面中添加须要的Fragment、建立继承自Fragment的类

② 设计Fragment对应的xml界面

③ 重载Fragment类中的函数onCreateView、改写return inflater.inflate(R.layout.bfragment, container, false);便可。

6.事件监听

(1)键盘事件setOnKeyListener

监听器中的函数的返回值为true将阻止事件传递给界面元素,界面元素就不会更新;程序中和事件有关的变量,它的信息能够类的声明中找到。

(2)触摸事件setOnTouchListener

比较典型的函数

值的说明

函数的说明

getAction()

ACTION_DOWN、ACTION_UP、ACTION_MOVE等

获取动做

getX()、getY()

 

获取相对坐标,相对前一个位置

getRawX()、getRawY()

 

获取绝对坐标

getPressure()

 

触点的压力

getSize()

 

触点的尺寸

getHistorical…()

 

获取历史数据中的第几个数据

4、组件通讯与广播

1.Intent

不论这些组件是否在一个应用程序中均可以用Intent进行通讯,显式通讯须要指明组件具体的类,隐式通讯发出动做便可、信息的接收方由系统决定。

(1)显式通讯,好比用Intent启动一个activity(这两个activity都已经在Manifest中注册):

Intent intent=new Intent(IntentDemoActivity.this,NewActivity.class);

startActivity(intent);

(2)隐式通讯,由动做触发:

Internt intent=new Intent(Intent.ACTION_VIEW,Uri.parse(“http://cn.bing.com/”));

startActivity(intent);

动做

说明

ACTION_VIEW

提供浏览的activity,Uri“http://...”表示网页地址、“tel:..”是电话号码

   

(3)获取子activity的返回值

父activity中设置子activity的标签,以后发送消息,好比:

SubActivity1就是一个用于区分不一样子activity的标签

Intent intent=new Intent(MainActivity.this, Activity1.class);

startActivityForResult(intent,SubActivity1);

子activity封装Uri信息,并设置结果,好比:

finish()无关紧要

Uri data=Uri.parse(editText.getText().toString());

Intent result=new Intent(null, data);

setResult(RESULT_OK, result);

finish();

父activity接收消息,须要重载函数onActivityResult:

函数的参数依次是标签、设置的结果标记、Uri数据;在函数中写须要的代码

2.Intent过滤器

这是隐式启动的匹配机制:当应用安装到Android系统的时候,会注册本身组件和Intent过滤器,这样系统就能够经过Intent过滤器映射每个Intent请求到相应的组件上;能够在Manifest配置文件中、特定的组件下定义<intent-filter>节点,获得组件的Intent过滤器

(1)Intent过滤器的标签

标签

属性

说明

<action>

android:name

动做,VIEW视图、包名

<category>

android:category

分类,LAUNCHER启动时最早被显示、DEFAULT默认

<data>

android:host

数据

指定主机名

android:mimetype

指定activity能处理的文档类型

android:path

Uri路径

android:port

端口号

android:scheme

指定的协议

(2)使用Intent过滤器

若是一个activity的过滤器是这样定义的:

<intent-filter>

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

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

<data android:scheme="schemodemo" android:host="edu.hrbeu" />

</intent-filter>

那么能够用Intent这样调用activity:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("schemodemo://edu.hrbeu/"));

startActivity(intent);

2.广播

(1)发出信号

须要一个区别于其余全局消息的标志,能够是程序包的名称,以后发送键值对形式的信号:

Intent intent=new Intent("com.example.demo0");

intent.putExtra("key", editText.getText().toString());

sendBroadcast(intent);

(2)接收信号

①Manifest文件下添加receiver,并声明它的过滤器(能够接收的消息类型),好比:

<receiver android:name=".Activity1">

<intent-filter>

<action android:name="com.example.demo0"/>

</intent-filter>

</receiver>

②定义一个activity,好比是Activity一、它继承自BroadcastReceiver,以后重载onReceive函数用来处理接收到的数据:

String value=intent.getStringExtra("key");

Toast.makeText(context, value, Toast.LENGTH_SHORT).show();

5、后台服务

指的是没有界面且长时间在后台运行的应用功能,很典型的是Service服务组件,好比MP3播放器,界面关闭后音乐还在播放,这就须要用到Service,此外Service还能够用于进程间的通讯。

1.java和CC++易混淆的语法

boolean是java中的布尔值

java类中的变量声明立刻就能够初始化,这点和CC++不一样

null至关于CC++中的NULL

2.Service的生命周期

clip_image004

3.本地服务

(1)显式使用Service

① Manifest中注册Service:

<service android:name=".RandomService"></service>

② 定义一个activity继承自Service,能够在onStart函数中、也能够其余合理的地方写须要的功能

③ 显式调用、中止Service:

final Intent intent=new Intent(MainActivity.this, RandomService.class);

startService(intent);

stopService(intent);

(2)隐式使用Service

④ Manifest中注册Service,不一样的是须要添加过滤器(声明能够接收的数据类型,甚至能够精确到Service类的名字):

<service android:name=".RandomService">

<intent-filter>

<action android:name="com.example.demo0"/>

</intent-filter>

</service>

⑤ 定义一个activity继承自Service,能够在onStart函数中、也能够其余合理的地方写须要的功能

⑥ 隐式调用、中止Service,隐式调用的时候发出动做action便可:

final Intent intent=new Intent("com.example.demo0");

startService(intent);

stopService(intent);

4.多线程

Android系统中若是一个线程处理的时间过长,会下降用户界面的响应速度、甚至使界面失去响应,将耗时的处理过程分解到子线程上是一个可行的解决办法。

(1)在主线程activity中定义Handle变量,用来接收服务线程Runable中时刻变化的数据:

static Handle handle;

public static void updateGUI(服务线程传入的新数据){

handle.post(refreshLabel);

}

static Runable refreshLabel=new Runable(){

@Override

public void run() {

// TODO Auto-generated method stub

用新数据更新UI界面

}

}

(2)Service中运用多线程:

⑦ 定义用于事务处理的线程:

Thread serviceThread;

Runnable backgroundWork = new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

try {

while (!Thread.interrupted()) {

//过程代码,用于提供服务

double randNum = Math.random();

MainActivity.updateGUI(randNum);

Thread.sleep(1000);

}

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

⑧ onCreate函数初始化这个线程:

serviceThread = new Thread(null, backgroundWork, "serviceThread");

⑨ onStart函数检查线程是否正常工做:

if (!serviceThread.isAlive()) {

serviceThread.start();

}

⑩ onDestory函数终止线程:

serviceThread.interrupt();

5.绑定服务

最简单的Service不接收参数也不返回参数,只接受调用;多线程的Service不接收参数本身产生变化,并经过调用主线程中的某些函数达到更新UI的目的;绑定服务的Service能够接收参数也能够返回参数,有Service的做用(避免界面失去响应、提供服务)、又能够像函数同样方便使用,这是颇有意义的。

(1)新建一个继承自service的类,好比MathService并在类中写入须要提供服务的函数

(2)新建一个IBinder对象,重载onBind()和onUnbind()函数:

IBinder mBinder=new LocalBinder();

class LocalBinder extends Binder{

MathService getService() {

return MathService.this;

}

}

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return mBinder;

}

@Override

public boolean onUnbind(Intent intent) {

// TODO Auto-generated method stub

return false;

}

(3)主线程的activity中声明一个服务类的变量,重载一个ServiceConnection变量:

MathService mathService = null;

ServiceConnection mConnection = new ServiceConnection() {

@Override

public void onServiceDisconnected(ComponentName name) {

// TODO Auto-generated method stub

//服务意外断开的时候,系统调用的函数

mathService = null;

}

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

// TODO Auto-generated method stub

mathService = ((MathService.LocalBinder) service).getService();

}

};

(4)绑定服务

Intent serviceIntent = new Intent(MainActivity.this, MathService.class);

bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);

(5)取消绑定

//这个函数未必有用

unbindService(mConnection);

mathService = null;

(6)提供服务

int res = mathService.add(a, b);

2. 远程服务

这是除Intent外的另外一种进程间的通讯方式,能够将服务和调用者以不一样应用的方式在一个系统中独立起来。

(1) 创建一个Service,以后用AIDL定义远程服务的接口,即写一个.aidl文件,好比:

AIDL即安卓接口定义语言,语法上相似java,可是AIDL容许参数有方向

package com.example.demo0;

interface IMathService{

int add(int a,int b);

}

(2) Service中须要一个Binder对象:

//也是这个Service提供的服务

IMathService.Stub mBinder=new IMathService.Stub() {

@Override

public int add(int a, int b) throws RemoteException {

// TODO Auto-generated method stub

return a+b;

}

};

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return mBinder;

}

@Override

public boolean onUnbind(Intent intent) {

// TODO Auto-generated method stub

return false;

}

(3) 新建一个调用者的工程,将Service中的AIDL连同包复制过来

(4) 须要一个ServiceConnection:

// 可以提供服务的对象

IMathService mathService;

ServiceConnection mConnection = new ServiceConnection() {

@Override

public void onServiceDisconnected(ComponentName name) {

// TODO Auto-generated method stub

mathService = null;

}

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

// TODO Auto-generated method stub

mathService = IMathService.Stub.asInterface(service);

}

};

(5) 绑定服务

Intent serviceIntent = new Intent();

serviceIntent.setAction("top.guomc.demo0.MathService");

bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);

(6) 取消绑定

unbindService(mConnection);

mathService = null;

(7) 提供服务

int res = 0;

try {

res = mathService.add(a, b);

} catch (RemoteException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

6.自定义数据的传输

在远程服务中,java基本数据类型的打包过程是自动完成的,可是自定义的数据(类)须要重载Parcelable接口来完成打包的过程

(1)自定义数据的.aidl文件,AllResult.aidl:

package top.guomc.demo0;

parcelable AllResult;

(2)提供服务函数的.aidl文件,IMathService.aidl:

package top.guomc.demo0;

import top.guomc.demo0.AllResult;

interface IMathService{

AllResult computeAll(int a,int b);

}

(3)自定义的类,这个类重载了Parcelable接口,AllResult.java

定义内部数据

//序列化

static Parcelable.Creator<AllResult> CREATOR = new Creator<AllResult>() {

@Override

public AllResult[] newArray(int size) {

// TODO Auto-generated method stub

return new AllResult[size];

}

@Override

public AllResult createFromParcel(Parcel source) {

// TODO Auto-generated method stub

return new AllResult(source);

}

};

定义构造函数

//内部数据写到包

@Override

public void writeToParcel(Parcel dest, int flags) {

// TODO Auto-generated method stub

dest.writeInt(addRes);

dest.writeInt(subRes);

dest.writeInt(mulRes);

dest.writeDouble(divRes);

}

(4)定义Service,MathService.java:

IMathService.Stub mBinder = new IMathService.Stub() {

@Override

public AllResult computeAll(int a, int b) throws RemoteException {

// TODO Auto-generated method stub

int addRes = a + b;

int subRes = a - b;

int mulRes = a * b;

double divRes = (double) a / b;

AllResult res = new AllResult(addRes, subRes, mulRes, divRes);

return res;

}

};

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return mBinder;

}

@Override

public boolean onUnbind(Intent intent) {

// TODO Auto-generated method stub

return false;

}

(5)将服务方的自定义类型连同.aidl、目录复制到接收方

(6)ServiceConnection、绑定服务、取消服务和上面同样

(7)提供服务

AllResult allResult = null;

try {

allResult = mService.computeAll(a, b);

} catch (RemoteException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

用定义过的getter函数将allResult的内部数据获取出来

6、数据存储与访问

SharedPreferences用于存取应用临时产生的数据、文件用于存取应用的非结构化数据、资源用于存取应用的内置数据、数据库用于存取应用的结构化数据,数据库能够完成以上目标

1.SharedPreferences

简单的键值对读写,xml文件将保存在/data/data/包名/shared_prefs/下;若是面对的是复杂类型的数据或是要保存到SD卡上,这种方式仍是有缺陷的

(1)声明SharedPreferenes的名字和模式:

static final String PREF_NAME="person";

static final int MODE=Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE;

访问模式:

MODE_PRIVATE

私有

MODE_WORLD_READABLE

全局读

MODE_WORLD_WRITEABLE

全局写

(2)在onStart()中获取一个SharedPreferences,读取用户个性化的数据来作初始化(通常程序都会这么作):

SharedPreferences sp=getSharedPreferences(PREF_NAME, MODE);

editText1.setText(sp.getString("name", "Tom"));

(3)在onStop()中获取一个SharedPreferences,用来保存数据到xml

SharedPreferences sp=getSharedPreferences(PREF_NAME, MODE);

SharedPreferences.Editor editor=sp.edit();

editor.putString("name", editText1.getText().toString());

2.文件存储

文件会被保存在/data/data/包名/files/目录下

(1)打开文件准备写数据

FileOutputStream fos(String filename,Context.mode);

mode的选择是:

MODE_PRIVATE

私有

MODE_APPEND

追加

MODE_WORLD_READABLE

全局可读

MODE_WORLD_WRITEABLE

全局可写

(2)写文件

String str=”Some data啊”;

fos.write(str.getBytes());

fos.flush();

fos.close();

(3)打开文件准备读数据

FileInputStream fis=openFileInput(String filename);

读文件

byte[] readBytes=new byte[fis.available()];

while(fis.read(readBytes)!=-1);

String str=new String(readBytes);

3.外部存储

在SD卡T-Flash上存储的数据是没有访问权限的控制的,可是能够保存一些大文件而不占用内部存储器的空间,模拟器启动时会自动加载SD卡出现新的路径/mnt/sdcard/,文件会被存储在/storage/sdcard/下

在AndroidManifest.xml中设置加载卸载文件系统、向外部存储器读写数据的权限

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

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

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

(1)写数据

String tmpFileName = "SdcardFile-" + System.currentTimeMillis() + ".txt";

File dir = new File("/sdcard/");

if (dir.exists() && dir.canWrite()) {

fileName = dir.getAbsolutePath() + "/" + tmpFileName;

File newFile = new File(fileName);

try {

newFile.createNewFile();

if (newFile.exists() && newFile.canWrite()) {

FileOutputStream fos = new FileOutputStream(newFile);

// str是要写入的String类型数据

fos.write(randNum.getBytes());

fos.flush();

fos.close();

stateView.setText(tmpFileName + "已写入SD卡");

randNumView.setText("");

}

} catch (Exception e) {

Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();

}

}

(2)读数据

File dir = new File("/sdcard/");

if (dir.exists() && dir.canWrite()) {

File newFile = new File(fileName);

try {

newFile.createNewFile();

if (newFile.exists() && newFile.canRead()) {

FileInputStream fis = new FileInputStream(newFile);

byte[] readBytes = new byte[fis.available()];

while (fis.read(readBytes) != -1);

String str = new String(readBytes);

randNumView.setText("读取的对应内容是:\n" + str);

}

} catch (Exception e) {

e.printStackTrace();

}

}

4.资源文件

视频、音乐、图片等原始文件放置在项目的/res/raw/下、在应用打包编译的时候不容许修改;xml做数据的文件放置在/res/xml/下,在打包编译的时候会被转换为二进制文件、以提升访问的效率;在项目中能够直接新建获得

(1)读取原始文件

Resources res=MainActivity.this.getResources();

try{

//raw_file是对应的原始文件名、不含后缀

InputStream ips=res.openRawResource(R.raw.raw_file);

byte[] readBytes=new byte[ips.available()];

while(ips.read(readBytes)!=-1);

ips.close();

//str是读出的String类型变量

String str=new String(readBytes,"utf-8");

}catch(Exception e){

e.printStackTrace();

}

(2)读取二级xml文件,好比

<people>

<person name=”李” age=”21” height=”1.81”/>

<person name=”王” age=”25” height=”1.76”/>

<person name=”张” age=”20” height=”1.69”/>

</people>

//people是对应目录下的xml文件名、不含后缀

XmlPullParser parser = MainActivity.this.getResources().getXml(R.xml.people);

String str = "";

try {

while (parser.next() != XmlPullParser.END_DOCUMENT) {

//用于接收键值对中键的信息

String tmp = parser.getName(), name = null, age = null, height = null;

if (tmp != null && tmp.equals("person")) {

int i, count = parser.getAttributeCount();

for (i = 0; i < count; ++i) {

//获取键值对的信息

String attrName = parser.getAttributeName(i);

String attrValue = parser.getAttributeValue(i);

if (attrName != null && attrName.equals("name"))

name = attrValue;

if (attrName != null && attrName.equals("age"))

age = attrValue;

if (attrName != null && attrName.equals("height"))

height = attrValue;

if(name!=null && age!=null && height!=null)

str += "姓名:" + name + ",年龄:" + age + ",身高:" + height + "\r\n";

}

}

}

displayView.setText(str);

} catch (Exception e) {

Log.e("ResourceFileDemo", e.getMessage(), e);

}

5. 数据库存储

数据保存在/data/data/包名/databases/下,默认是私有的;sqlite3在sdk/platform-tools/下,能够经过同目录的adb.exe链接模拟器的Linux系统作进一步的shell操做

(1)手工建库

能够经过adb的shell命令建立对应目录下的文件夹databases、再建立.db文件,可是在shell状态下不能输入中文等unicode字符;也能够经过eclipse的DDMS建立对应的文件夹、再上传.db文件

(2)代码建库

使用多个DBAdapter就能够实现多数据集多表、单数据集单表的操做,具体代码见../io/DBAdapter0.0.rar

①Cursor指针的经常使用方法

moveToFirst()

移动到第一条数据上

moveToNext()

移动到下一条数据上

moveToPrevious()

移动到上一条数据上

getCount()

获取集合中元素的数目

getColumnIndexOrThrow()

获取指定属性名称的序号,属性不存在会抛出异常

getColumnName()

获取指定序号的列属性名称

getColumnNames()

获取列属性的数组

getColumnIndex()

根据列名称返回序号

moveToPosition()

将指针移动到指定的数据上

getPosition()

返回当前指针的位置

②query()的参数,从左到右

还有一种比较方便的办法rawQuery(SQL语句,参数说明的数组),若是SQL语句完整(语句中没有?)、数组的地方填null

参数类型

说明

String

表的名称

String[]

属性列的名称

String

对应select语句,查询条件

String[]

模糊查询的替换符

String

对应groupBy语句,分组方式

String

对应having语句,组的过滤器

String

对应orderBy语句,排序方式

6.ContentProvider

一种应用层面共享数据的方法,ContentProvider实现后、其余应用经过ContentResolver对象发送URI修改其中的共享数据库;实现的代码具体见io/ ContentProvider0.0.rar

(1)将数据项进行封装
(2)继承ContentProvider并重载其中的方法
(3)AndroidManifest.xml中注册ContentProvider

要注意的是加上SDK的版本限制容易致使错误

(4)其余应用和共享数据库的交互

操做数据库

ContentValues封装数据、再封装到Uri中、ContentResolver执行对应功能的函数

获取数据库中的数据

Cursor接收ContentResolver的返回值,数据再从Cursor中获取

7、位置和地图

8、Widget组件开发

9、Android NDK

10、特效

1.tab标签页

继承自Activity的类能够管理这些标签页,若是要实际使用,还须要在AndroidManifest<application/>下面注册这个类。

(1)在layout设计界面中制做tab标签页,并将标签页加入R的id资源中

(2)建立继承自TabActivity的类做为入口,用getTabHost()初始化tabHost

(3)将tab标签页转为java管理的对象,好比LayoutInflater.from(this).inflate(R.layout.tab1, tbHost.getTabContentView());

(4)tabHost添加上这些标签页,好比tbHost.addTab(tbHost.newTabSpec("tab3").setIndicator("FrameLayout").setContent(R.id.layout3));,其中“tab3”是程序中的标记,而“FrameLayout”是标签将显示的标题。

11、附录

1.参考网址

www.oracle.com/

下载JDK

   
   

2.eclipse快捷键

alt+shfit+n

新建工程

alt+shift+r

重命名

alt+shift+s

选择内置函数,好比继承某些内置的方法

alt+shift+j

生成注释块

ctrl+d

删除一行或者选中块

alt+/

关键字提示

alt+enter

属性

alt+上下键

移动选中块代码

选中文件alt+shift+r

重命名

ctrl+alt+上下键

复制选中块,能够在preference中设置

ctrl+shift+f

快速格式化

ctrl+shift+b

加断点、去掉断点

选中,ctrl+shift+/或者\

注释、反注释

ctrl+/

快速注释、反注释一行

ctrl+l

快速到某一行

ctrl+f11

运行代码

ctrl+点击

查看更详细的定义

alt+shift+a

列编辑

3.adb命令

adb即Android Debug Bridge安卓调试桥,用于链接Linux系统、管理android设备或模拟器;用命令行工具进入platform-tools,下面的命令都须要在前面加上adb,才会有效

install .apk的完整路径

安装某个安卓文件

uninstall .apk的完整包名

卸载某个安卓文件

help

帮助命令

version

adb的版本信息

devices

正在运行的模拟器

shell 命令

执行shell命令

shell

进入shell模式

push 本地文件 目标路径

上传本地文件

pull 目标路径 [本地路径]

将设备上的文件下载下来,本地路径默认是adb的路径

4.avd命令

avd即安卓虚拟设备,进入tools目录下,能够用命令行建立和编译安卓程序;

android list targets

镜像文件清单

android list avds

avd的清单

   

5.模拟器设置中文

设置->语言和输入法;

语言,选择中文(中国);

键盘和输入法,选择谷歌拼音输入法;

默认,选择谷歌拼音输入法;

关闭硬件物理键盘

相关文章
相关标签/搜索