目录 html
1、构建Android开发环境... 4 java
1.用eclipse作Android的开发... 4 android
2.用手机作虚拟设备... 4 sql
2、生命周期... 4 shell
2.参考的调用顺序... 5 api
(1)日志点... 5 多线程
(2)应用程序提示... 6 oracle
(2)继承ContentProvider并重载其中的方法... 29
(3)AndroidManifest.xml中注册ContentProvider 29
正文
(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) 建立新项目
下面用的是SUMSUNG手机,这种办法只能看到当前应用的信息
(1)About phone->Software information
(2)连续点击Build number3次
(3)在Developer options中打开USB debugging,并选择适当设置
(4)用USB链接手机,就能够经过IDE选择这个手机作模拟设备,运行须要调试的应用
程序在Android系统中从启动到终止的全部过程,程序不能控制自身的生命周期而受系统的调度和控制。
onSaveInstanceStae()用于保存activity界面的临时信息、信息通常放在Bundle中,onRestoreInstanceState()用于程序被销毁时恢复临时信息、好比程序遇到锁屏或者被系统中断,可是它们都不是生命周期的时间回调函数。
onCreate() |
用于activity的初始化、建立链接、绑定数据等,是第一个被调用的函数 |
onStart() |
activity显示在屏幕上时被调用 |
onRestart() |
activity从新启动时调用、以后调用onResume()继续和用户交互 |
onResume() |
获取屏幕焦点、接收用户输入时被调用 |
onPause() |
程序被其余窗口覆盖,系统调用函数“暂停”程序、以后调用onSaveInstanceStae()保存临时信息 |
onStop() |
用户不可见时,进入中止对activity更新 |
onDestroy() |
程序调用finish()函数或者被系统终结的时候调用 |
当用户离开当前页面又从新回到这个页面时,会调用onStart()、onStop()
好比Log.i(String TAG,String cnt);,还能够选.w、.e等不一样的日志信息等级,查看日志的方法是在Logcat中创建过滤器,输入Filter Name、Tag的内容(即字符串TAG),选择日志的级别肯定便可。
好比Toast.makeText(MainActivity.this, "服务未绑定", Toast.LENGTH_SHORT).show();
做为前两种办法的补充,若是前面的办法还不能分析出错误缘由,再考虑DevTools提供的信息。
模型、视图、控制器,控制器加工用户输入的数据、交给处理核心“模型”,最终由“模型”来更新视图。
用eclipse的layout设计界面制做静态的UI,用java控制动态的内容、先声明一个控件变量而后用findViewById引用xml中的资源进行初始化。具体的函数能够查阅android的API文档。
控件的属性在设计界面中有,也能够查阅android的手册。
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() |
获取输入的焦点 |
Button、ImageButton
CheckBox用于多选、RadioGroup和RadioButton用于单选。
经常使用函数
isChecked() |
控件是否被选中 |
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);
ListView中若是内容不少,就会出现滚动条;若是没有内容,将不显示控件。
监听器属于控件的方法,将使用内部类、若是出现错误多是没有加上View.,在android_api.chm中也有具体的说明。好比OnClickListener、
① 控件独占一个监听器
好比列表控件中给每一个子项设置监听器,listView.setOnItemClickListener(new AdapterView.OnIOnItemClickListener(){…});
② 多个控件共享一个监听器
方法是定义一个监听器,而后用v.getId()区分各个控件写上须要的代码,最后控件绑定这个监听器。若是一种类型的控件屡次出现,尽可能用这种方法设置监听器,消除一些没必要要的冗余,。
布局之间能够相互嵌套,按经常使用的程度分为:
LinearLayout能够选择水平也能够选择垂直,还能够像html中table的行列组合使用、这样就灵活多了。
RelativeLayout使用相对的位置以适应不一样的屏幕尺寸,灵活并且比较稳定。
和表格布局相似,可是网格布局中的元素能够占用多个网格,而表格布局中的元素不能跨行跨列。
TableLayout默认控件独占一行,TableRow默认控件尽可能放在一行。
在layout设计界面中已经找不到,可是在手动建立布局的xml文件的时候有这样一种布局,部件的位置像坐标同样严格的受到数值的控制、不一样的设备上效果不必定好。
一种相似坐标的自由布局FrameLayout
能够在onCreate函数中用getActionBar().hide();隐藏操做栏的菜单,也能够经过修改app的主题styles作到一样的效果
在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初始化 |
具备快捷菜单的元素,若是按住它超过两秒,就会启动它的快捷菜单;和菜单资源相似,不一样的是须要重载onCreateContextMenu函数,最后对须要的元素注册快捷菜单,方法是registerForContextMenu。
把页面中可能重复使用的部分作成Fragment,在一个activity中调用、提升了代码的可重用性。
① layout设计界面中添加须要的Fragment、建立继承自Fragment的类
② 设计Fragment对应的xml界面
③ 重载Fragment类中的函数onCreateView、改写return inflater.inflate(R.layout.bfragment, container, false);便可。
监听器中的函数的返回值为true将阻止事件传递给界面元素,界面元素就不会更新;程序中和事件有关的变量,它的信息能够类的声明中找到。
比较典型的函数 |
值的说明 |
函数的说明 |
getAction() |
ACTION_DOWN、ACTION_UP、ACTION_MOVE等 |
获取动做 |
getX()、getY() |
获取相对坐标,相对前一个位置 |
|
getRawX()、getRawY() |
获取绝对坐标 |
|
getPressure() |
触点的压力 |
|
getSize() |
触点的尺寸 |
|
getHistorical…() |
获取历史数据中的第几个数据 |
不论这些组件是否在一个应用程序中均可以用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数据;在函数中写须要的代码
这是隐式启动的匹配机制:当应用安装到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);
须要一个区别于其余全局消息的标志,能够是程序包的名称,以后发送键值对形式的信号:
Intent intent=new Intent("com.example.demo0");
intent.putExtra("key", editText.getText().toString());
sendBroadcast(intent);
①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();
指的是没有界面且长时间在后台运行的应用功能,很典型的是Service服务组件,好比MP3播放器,界面关闭后音乐还在播放,这就须要用到Service,此外Service还能够用于进程间的通讯。
boolean是java中的布尔值 |
java类中的变量声明立刻就能够初始化,这点和CC++不一样 |
null至关于CC++中的NULL |
① Manifest中注册Service:
<service android:name=".RandomService"></service>
② 定义一个activity继承自Service,能够在onStart函数中、也能够其余合理的地方写须要的功能
③ 显式调用、中止Service:
final Intent intent=new Intent(MainActivity.this, RandomService.class);
startService(intent);
stopService(intent);
④ 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);
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();
最简单的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();
}
在远程服务中,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的内部数据获取出来
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());
文件会被保存在/data/data/包名/files/目录下
FileOutputStream fos(String filename,Context.mode);
mode的选择是:
MODE_PRIVATE |
私有 |
MODE_APPEND |
追加 |
MODE_WORLD_READABLE |
全局可读 |
MODE_WORLD_WRITEABLE |
全局可写 |
String str=”Some data啊”;
fos.write(str.getBytes());
fos.flush();
fos.close();
FileInputStream fis=openFileInput(String filename);
读文件
byte[] readBytes=new byte[fis.available()];
while(fis.read(readBytes)!=-1);
String str=new String(readBytes);
在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"/>
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();
}
}
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();
}
}
视频、音乐、图片等原始文件放置在项目的/res/raw/下、在应用打包编译的时候不容许修改;xml做数据的文件放置在/res/xml/下,在打包编译的时候会被转换为二进制文件、以提升访问的效率;在项目中能够直接新建获得
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();
}
<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);
}
数据保存在/data/data/包名/databases/下,默认是私有的;sqlite3在sdk/platform-tools/下,能够经过同目录的adb.exe链接模拟器的Linux系统作进一步的shell操做
能够经过adb的shell命令建立对应目录下的文件夹databases、再建立.db文件,可是在shell状态下不能输入中文等unicode字符;也能够经过eclipse的DDMS建立对应的文件夹、再上传.db文件
使用多个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语句,排序方式 |
一种应用层面共享数据的方法,ContentProvider实现后、其余应用经过ContentResolver对象发送URI修改其中的共享数据库;实现的代码具体见io/ ContentProvider0.0.rar
要注意的是加上SDK的版本限制容易致使错误
操做数据库 |
ContentValues封装数据、再封装到Uri中、ContentResolver执行对应功能的函数 |
获取数据库中的数据 |
Cursor接收ContentResolver的返回值,数据再从Cursor中获取 |
继承自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”是标签将显示的标题。
www.oracle.com/ |
下载JDK |
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 |
列编辑 |
adb即Android Debug Bridge安卓调试桥,用于链接Linux系统、管理android设备或模拟器;用命令行工具进入platform-tools,下面的命令都须要在前面加上adb,才会有效
install .apk的完整路径 |
安装某个安卓文件 |
uninstall .apk的完整包名 |
卸载某个安卓文件 |
help |
帮助命令 |
version |
adb的版本信息 |
devices |
正在运行的模拟器 |
shell 命令 |
执行shell命令 |
shell |
进入shell模式 |
push 本地文件 目标路径 |
上传本地文件 |
pull 目标路径 [本地路径] |
将设备上的文件下载下来,本地路径默认是adb的路径 |
avd即安卓虚拟设备,进入tools目录下,能够用命令行建立和编译安卓程序;
android list targets |
镜像文件清单 |
android list avds |
avd的清单 |
设置->语言和输入法;
语言,选择中文(中国);
键盘和输入法,选择谷歌拼音输入法;
默认,选择谷歌拼音输入法;
关闭硬件物理键盘