Android 四大元件,五大儲存,六大布局
Android 四大元件
android四大元件分別是:Activity, service,content provider,broadcast receiver
一、Activity
1、概念:
android 中,Activity 相當於一個頁面,可以在Activity中新增Button、CheckBox 等控制元件,一個android 程式有多個Activity組成。
2、生命週期:
3、四中啟動模式
Standard 模式 : standard 模式是android 的預設啟動模式,在這種模式下,activity可以有多個例項,每次啟動Activity,無論任務棧中是否已經存在這個activity的例項,系統都會建立一個新的activity例項。
SingleTop 模式: 棧頂模式,當一個singleTop模式的activity 已經位於棧頂時,再去啟動它時,不在建立例項,如果不在棧頂,就會建立例項。
SingleTask 模式 : 單任務模式,如果啟動的activity 已經存在於 任務棧中,則會將activity移動到棧頂,並將上面的activity出棧,否則建立新的例項
SingleInstance 模式 :單例項模式,一個activity 一個棧。
4、三種跳轉方式
顯示啟動 :
Intrent 內部直接宣告要啟動的activity所對應的的class
Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intnet);
隱式啟動
進行三個匹配,一個是activity,一個是category,一個是data,全部或者部分匹配,應用於廣播原理
- 清單檔案中 裡配置activity屬性,activity的名字要和跳轉內容一樣
<activity android:name="com.exanple.android.tst.secondActivity" android:label = @string/title> <intent=filter> <action android:name="com.exanple.android.tst.secondActivity/> <category android:name="android.intent.category.DEFAULT"/> <intent-filter/> </activity>
- 在需要跳轉的地方
Intent intent = new Intent("com.example.android.tst.secondActivity");
startActivity(intnet);
跳轉後再返回,能獲取返回值
Intent in = new Intent(MainActivity.this,OtehrActivity.class);
in.putExtra("a",a);
startActivityForResult(in,1000);
在OTherActivity中設定返回值
Intent int = new Intent();
int.putExtra("c",c);
setResult(1001,int);
finish();
在MainActivity中獲取返回值
@Override
protected void onActivityResult(int requestCode, int resultCode ,Intent data) {
super.onActivityResult(requestCode,resultCode,data);
if(requestCode == 1000){
if(resultCode == 1001){
int c = data.getExtra("c",0);
}
}
}
Service
定義一個Server
專案內Server包 右鍵 --> New --> Service --> Service 或者直接建立Class類,繼承Service並重寫IBinder方法
public class MyService extends Service{
public MyService(){
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
重寫Service的 onCreate()、onStartCommand()和onDestory()方法。其中 onCreate() 方法在服務建立的時候呼叫、onStartCommand() 方法會在每次服務啟動的時候呼叫、onDestory() 方法會在服務銷燬的時候呼叫。
通常情況下,如果我們希望服務一旦啟動就立刻去執行任務,就可以將邏輯解除安裝onStartCommand() 方法裡。
另外需要注意的是,每個服務都需要在Androidmanifest.xml 中進行註冊才能生效:
<application
....>
...
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
</service>
</application>
啟動和停止服務
啟動服務:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent); //啟動服務
停止服務:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); //停止服務
使用前臺服務
前臺服務與普通服務的最大區別在於,它會一直有一個正在執行的圖示在系統的狀態列中,下拉狀態列後可以看到更加詳細的內容,非常類似於通知的效果。
public class MyService extends Service{
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0 , intent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(" this is content titile")
.setContentText("this is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher);
.setLargeIcon(BitmapFactory.decodeResource(getResource(),
R.mipmap.ic_launcher))
.setContentIntent(pi)
.build();
startForeground(1,notification);
}
構造一個Notification物件後並沒有使用NotificationManager 來講通知顯示出來,而是呼叫了startForeground()方法,該方法會將MyService變成一個前臺服務,並在系統狀態列中顯示出來。
使用IntentService
服務中的程式碼都預設執行在主執行緒中,如果直接在服務中執行耗時操作很容易出現ANR(Application not Responding)
所以這個時候需要用到Android多執行緒程式設計技術,我們應該在服務的每個具體的方法裡啟動一個子執行緒,然後在這裡去處理那些耗時的操作:
public class MyService extends Service{
...
@Override
public int onStartCommand(Intent intent , int flags, int startId){
new Thread(new Runnable(){
public void run(){
//處理具體的邏輯
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
}
但是,這種服務一旦啟動之後,就會一直處於執行狀態,必須呼叫stopService()或者stopSelf()方法才能讓服務停止下來,所以,如果想要實現讓一個服務在執行完畢後自動停止的功能,就可以這樣寫:
public class MySerivce extends Servcie{
...
@Override
public int onStartCommand(Intent intent, int flats , int startId){
new Thread(new Runnable(){
public void run(){
//處理具體的邏輯
stopSelf();
}
});
}
}
雖說這樣的寫法並不複雜,但是總會有一些程式設計師忘記開啟執行緒或者忘記呼叫stopSelf() 方法。為了簡單建立一個非同步、會自動停止的服務。Android專門提供了一個IntentService類
public class MyIntentService extends IntentService{
public MyIntentService(){
super("MyIntentService"); //呼叫父類的有參構造方法
}
@Override
protected void onHandleIntent(Intent intent){
//列印當前的執行緒ID
Log.e("mylog","Thread id is” + Thread.cuttentThread().getId();
}
@Override
public void onDestory(){
super.onDestory();
Log.e("mylog","on Destory executed");
}
}
首先這裡提供一個無參的構造方法,並且必須在其內部呼叫父類的有參構造方法。然後要在子類中去實現onHandleIntent() 這個抽象方法,在這個方法中可以去處理一些邏輯,而且不用擔心ANR,因為這個方法已經是在子執行緒中運行了。
IntentService執行緒的呼叫:
Intent intent = new Intent(this, MyIntentService.class);
startServcie(intent);
如此,執行緒就會自動啟動並執行邏輯,執行完畢後自動關閉。這就是IntentService 的好處,能夠自動開啟和關閉;
Content Provider
對於每一個應用程式來說,如果想要訪問內容提供器中共享的資料,就一定要藉助ContentResolver 類,可以通過Context中的getContentResolver() 方法獲取該類的例項。ContentResolver中提供了一系列的方法用於對資料進行CRUD操作,其中insert() 方法用於新增資料,update() 方法用於更新資料,delete() 方法用於刪除資料,query() 方法用於查詢資料。
不同於SQLiteDatabase,ContentResolver 中的增刪改查都是接收一個URl引數,這個引數被稱為內容URL。內容URL給內容提供器中的資料建立了唯一識別符號,它主要由兩部分組成:authority 和 path 。authority 是用於對不同的應用程式做區分的,一般為了避免衝突,都會採用程式包名的方式進行命名。path則是用於對同一應用程式中不同的表做區分,通常都會新增到authority後面:
content://com.example.app.provider/table1
content://com.example.app.provider/table2
在使用內容URL作為引數的時候,需要將URL轉換成URL物件:
Uri uri = Uri.parse("content://com.example.app.provider/table1")
現在我們就可以使用這個uri物件來查詢talbe1表中的資料了:
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder
);
對應引數的解釋:
query()方法引數 | 對應SQL部分 | 描述 |
---|---|---|
uri | from table_name | 指定查詢某個應用程式下的某個表 |
projection | select column1, column2 | 指定查詢的列名 |
selection | where column=value | 指定where約束條件 |
selectArgs | - | 為where中的佔位符提供具體的值 |
orderBy | order by column1, column2 | 指定查詢結果的排序方式 |
查詢完之後,就可以從遊標中取值了:
if(cursor != null){
while(cursor.moveToNext()) {
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}
增刪改查
新增資料
ContentValues values = new ContentValues();
values.put(“column1”, "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);
更新資料
ContentValues valuse = new ContentValues();
valuse.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[]{"text", 1});
刪除資料
getContentResolver().delete(uri , "column2 = ?", new String[]{ "1"});
例項.
讀取系統聯絡人
讀取系統聯絡人需要宣告許可權,如果系統是6.0以後的,需要申請執行時許可權
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
}else {
readContacts(); //讀取聯絡人
}
private void readContacts(){
Cursor cursor = null;
try{
//查詢聯絡人資料
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
if(cursor!=null){
while(cursor.moveToNext()){
//獲取聯絡人姓名
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
//獲取聯絡人電話號碼
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
list.add(name+"\n"+number);
}
}
}catch(Exception e){
e.printStackTrace()
}finally{
if(cursor != null){
cursor.close();
}
}
}
@Override
public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults){
switch(requestCode){
case 1:
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
readContacts();
}else {
//您拒絕了許可權
}
}
}
建立自己的內容提供器
建立自己的內容提供器,需要去繼承 ContentProvider 類,ContentProvider 類中有6個抽象方法,我們在使用子類繼承它的時候,需要將這6個方法全部重寫。
public class MyProvider extends ContentProvider{
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, Stirng selection, String[] selectionArgs, String sortOrder){
return null;
}
@Overrride
public Uri insert(Uri uri , ContentValues values){
return null;
}
@Override
public int update(Uri uri, ContentValuse values, String selection, String[] selectionArgs){
return 0;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs){
return 0;
}
@Override
public String getType(Uri uri){
return null;
}
}
URI 的主要格式有以下兩種
content://com.example.app.provider/table1
content://com.example.app.provider/table1/1
* : 表示匹配任意長度的任意字元
# : 表示匹配任意長度的數字
//一個能夠匹配任意表的內容URI格式就可以寫成:
content://com.example.app.provider/*
//一個能夠匹配表中任意一行資料的內容URI格式就可以寫成:
content://com.example.app.provider/table1/#
Broadcast Receiver
android 廣播分為兩個角色:廣播發送者、廣播接收者
android 廣播:
1),用於不同元件間的通訊(含:應用內/不同應用之間)
2),用於多執行緒通訊
3),與android系統的通訊
自定義廣播接收者
- 繼承BroadcastReceive 基類
- 必須重寫抽象方法onReceive()方法
1,廣播接收器收到相應廣播後,會自動呼叫onReceive() 方法
2,一般情況下,onReceive方法會會涉及與其他元件之間的互動,如 傳送Notiotification,啟動server等
3,預設情況下,廣播接收器執行在UI執行緒,因此,onReceive方法不能執行耗時操作,否則將導致ANR
廣播接收器註冊
註冊的方式有兩種:靜態註冊、動態註冊
靜態註冊
- 註冊方式:在AndroidManifest.xml 裡通過<receive 標籤宣告
- 屬性說明
<receiver
android:enable="true"/"false"
//此broadcastReceiver 是否接受其他應用發出的廣播
//預設值時由receiver 中d有無inter-filter決定,如果有,預設true,否則預設false
android:exported="true"/"false"
android:icon="drawable resource"
android:label="string resource"
//繼承BroadcastReceiver子類的類名
android:name=".mBroadcastReceiver"
//具有相應許可權的廣播發送者傳送的廣播才能被此BroadcastReceiver所接收;
android:permission="string"
//BroadcastReceiver執行所處的程序
//預設為app的程序,可以指定獨立的程序
//注:Android四大基本元件都可以通過此屬性指定自己的獨立程序
android:process="string" >
//用於指定此廣播接收器將接收的廣播型別
//本示例中給出的是用於接收網路狀態改變時發出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
註冊示例:
<receiver
//此廣播接收者類是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用於接收網路狀態改變時發出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
當此APP首次啟動時,系統會自動例項化mBroadcastReceiver類,並註冊到系統中。
動態註冊
- 註冊方式:在程式碼中呼叫Context.registerReceiver() 方法
- 具體程式碼如下:
// 1. 例項化BroadcastReceiver子類 & IntentFilter
mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
// 2. 設定接收廣播的型別
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
// 3. 動態註冊:呼叫Context的registerReceiver()方法
registerReceiver(mBroadcastReceiver, intentFilter);
//動態註冊廣播後,需要在相應位置記得銷燬廣播
unregisterReceiver(mBroadcastReceiver);
特別注意
動態廣播最好在onResume中註冊, onPause登出
原因:
1,對於動態廣播,有註冊必然得有登出,否則會導致記憶體洩漏
2,onPause在App死亡前一定會被執行,從而保證app死亡前一定會被登出,從而防止記憶體洩漏
兩種註冊方式的區別
廣播的傳送
廣播的傳送 = 廣播發送者 將此廣播的意圖(intent)通過 sendBroasdcast() 方法傳送出去
廣播的型別
- 普通廣播 系統廣播 有序廣播 粘性廣播 App 應用內廣播
特別注意:
對於不同註冊方式的廣播接收器回撥OnReceive(Context context,Intent intent)中的context返回值是不一樣的:
- 對於靜態註冊(全域性+應用內廣播),回撥onReceive(context,
intent)中的context返回值是:ReceiverRestrictedContext; - 對於全域性廣播的動態註冊,回撥onReceive(context, intent)中的context返回值是:Activity
Context; - 對於應用內廣播的動態註冊(LocalBroadcastManager方式),回撥onReceive(context,
intent)中的context返回值是:Application Context。 - 對於應用內廣播的動態註冊(非LocalBroadcastManager方式),回撥onReceive(context,
intent)中的context返回值是:Activity Context;
Android 五大儲存
SharedPreferences 方式
SharedPreferences 是使用鍵值對的方式進行儲存資料的。
想要使用SharedPreferences 來儲存資料,首先主要獲取到SharedPreferences 物件。Android提供了三種方法用於獲取SharedPreferences物件:
1,Context類中的getSharedPreferences()方法
//此方法接收兩個引數,一個引數用於指定SharedPreferences檔案的名稱,如果指定的檔案不存在則會建立一個,SharedPreferences檔案都是存放在/data/data/<package name>/shared_prefs/目錄下
//第二個引數用於指定操作模式,目前只有MODE_PRIVATE這種模式,和直接傳入0效果相同
SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age",13);
editor.putBoolean("married",false);
editor.apply();
2,Activity類中的getPreferences()方法
//這個方法和Context中的getSharedPreferences()方法很類似,不過它只接收一個操作模式,因為使用這個方法時會自動將當前活動的類名作為SharedPreferences的檔名
3,PreferencesManager類中的getDefaultSharedPreferences()方法
//這是一個靜態方法,它接收一個Context引數,並自動使用當前應用程式的包名作為字首來命名SharedPreferences檔案
得到了SharedPreferences物件後, 就可以開始想SharedPreferences檔案中儲存資料了,主要可以分為三步:
(1)呼叫SharedPreferences物件的edit()方法來獲取一個SharedPreferences.Editor物件
(2)向SharedPreferences.Editor 物件中新增資料,比如新增一個布林值,可以使用putBoolean() 方法
(3)呼叫apply()方法的新增的資料提交,從而完成資料儲存操作
SharedPreferences中讀取資料
SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE );
String name = pref.getString("name","");
int age = pref.getInt("age",0);
boolean married = pref.getBoolean("married", false);
檔案儲存方式
SQList 儲存方式
Android 為了讓我們能夠更加方便的管理資料庫,專門提供了一個SQLiteOpenHelper 幫助類,藉助這個類可以非常簡單的將資料庫進行建立好升級。
SQLiteOpenHelper 中有兩個非常重要的例項方法,getReadableDatabase() 和 getWritableDatabase() 。這兩個方法可以建立或者開啟一個現有的資料庫(如果資料庫存在則直接開啟,否則建立一個新的資料庫),並返回一個可對資料庫進行讀寫操作的物件。不同的是,當資料庫不可寫入(如磁碟空間已滿),getReadableDatabase方法返回的物件將以只讀的方式開啟資料庫,而getWeitableDatabase則出現異常
例子(在指定路徑下建立資料庫檔案 .db )
public class MainActivity extends Activity {
public static final String PATH_ONE = "KogBill";
public static final String PATH_NAME = "KogBill.db";
private SQLiteDatabase db; //宣告SQLiteDatabase ,該物件可以操作資料庫
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
String path1 = path + File.separator + PATH_ONE; //需要建立的路徑
String path2 = path + File.separator + PATH_ONE +
File.separator + PATH_NAME; //需要建立的檔案
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File f = new File(path1);
if( !f.exists()){ //建立資料庫檔案路徑
f.mkdirs();
}
//例項化MySQLiteHelper ,建立指定目錄下資料庫檔案,並建立表
MySQLiteHelper mSQL = new MySQLiteHelper(MainActivity.this, path2);
db = mSQL.getWritableDatabase();
}
class MySQLiteHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;//資料庫版本號
private static final String CREATE_TABLE = "create table kog_bill ("
+ "_id integer primary key autoincrement,"
+ "date text, "
+ "breakfast text, "
+ "lunch text,"
+ "dinner text,"
+ "happy text,"
+ "other text,"
+ "spare text)";
//方便建立例項,簡化構造方法,方法內呼叫4引數構造方法
//引數 name 可以是 資料庫名稱,也可以資料庫檔案路徑(即可以指定資料庫檔案路徑)
public MySQLiteHelper(Context context, String name) {
this(context, name, null, DATABASE_VERSION);
}
//必須要實現的方法
public MySQLiteHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 第一次建立資料庫時 才會呼叫
Log.e("mylog", "建立資料庫表");
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
根據上述程式碼,便獲得db物件,通過db(SQLiteDatabase)可進行資料庫的操作,如 db.query() db.delete()
如果我們想在建立一個數據庫表,參照上述程式碼,可以在SQLiteOpenHelper的onCreate方法中加入語句:
@Override
public void onCreate(SQLiteDatebase db) {
db.execSQL(CREATE_TABLE);
db.execSQL(CREATE_BOOK); //新建立一個數據庫表
}
然後重新執行一下,發現並沒有建立成功,因為KogBill.db資料庫已經存在,所以MySQLiteHelper 中的onCreate方法都不會執行,解決這個辦法的方法很簡單,只需要將db檔案刪除,重新執行,便可成功,但是原來資料庫中的資料都會被刪除。所以需要用到MySQLiteHelper中的update方法。
class MySQLiteHelper extends SQLiteOpenHelper{
.....
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("drop table if exists book"); //如果已經存在就刪除,防止重複建立
onCreate(db); // 再次執行onCreate 方法
}
}
但是onUpgrade方法預設是不執行的,如何讓onUpgrade方法執行,需要用到MySQLiteHelper 構造引數中的版本號:
private static final int DATABASE_VERSION = 1;// 將版本號 由 1 改為2
這裡將資料庫版本號由1改為2,表示對資料庫的升級
資料庫的增刪改查
新增資料
ContentValues values = new ContentValues();
values.put("date", str1.isEmpty()?"0.0":str1);
values.put("breakfast", ""+str2);
values.put("lunch", ""+str3);
values.put("dinner", ""+str4);
values.put("happy", ""+str5);
values.put("other", ""+str6);
values.put("spare", ""+str7);
long ii = db.insert("kog_bill", "", values);
values.clear();
if(ii != -1) {
Utils.showToast("儲存成功!", MainActivity.this);
}else {
Utils.showToast("儲存失敗!", MainActivity.this);
}
更新資料
ContentValues valus = new ContentValues();
valuse.put("other","12");
db.update("kogBill", values, "_id=?",new String[]{id});
刪除資料
db.delete("kogBill", "_id=?",new String[]{id});
查詢資料
db.query("kog_bill", new String[]{"_id","date","breakfast","lunch","dinner","happy","other","spare"}
, null, null, null, null, "date desc");
使用SQL操作資料庫
雖然Android 已經給我們提供了非常方便的API用於操作資料庫,不過總會有些人不習慣去使用這些輔助行的方法,而是更加青睞於直接使用SQL來操作資料庫,當然Android也是提供的。
新增資料
db.execSQL("insert into kogBill ("date","breakfest","lunch","dinner","happy","other","spare") values (?,?,?,?,?,?,?)", new String[]{"1921-1-1",“123”,“1”,“1”,“11”,“2”,“3”});
更新資料
db.execSQL("update kogBill set other = ? where _id = ? ", new String[]{"12",id});
刪除資料
db.execSQL("delete from kogBill where _id = ?”, new String[]{id});
使用 LitePal 操作資料庫
假設編譯環境為AndroidStudio。
1,引進包
dependencies{
compile fileTree(dir:'libs', include:['*.jar'])
compile 'com.android.support:appcompat-v7:23.2.0'
testCompile 'junt:junt:4.12'
compile 'org.litepal.android:core:1.3.2' //引入litepal包
}
2,配置litepal.xml 檔案
右鍵app/src/main 目錄->New -> Directory ,建立一個assets目錄,然後在 assets目錄下再新建一個litepal.xml 檔案,接著編輯檔案中的內容
<?xml version='1.0' encoding="utf-8"?>
<litepal>
<dbname value = "BookStore"></dbname>
<version value="1"></version>
<list></list>
</listepal>
其中,<dbname 標籤用來指定資料庫名,<version 用來指定資料庫版本號,<list 標籤用來指定所有對映模型。
最後還需要在配置以下 LitePalApplication, 修改AndroidManifest.xml 中的程式碼
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.litepaltest" >
<application
android:name="org.litepal.LitePalApplication" //配置 LitePalApplication
android:allowBackup="true"
.....
</application>
</manifest>
以上,LitePal的配置工作已經結束了,接下來使用LitePal。
首先將需要實現 javabean類 對應 資料庫表.
然後將javabean類新增到對映模型列表中,修改litepal.xml 中的程式碼
<litepal>
<dbname value="kogBill" ></dbname>
<version value="1"></version>
<list>
<mapping class="com.example.litepaltest.book"></mapping> //javabean類的路徑
</list>
這樣所有工作就已經完成,現在只要進行任意一次資料庫的操作,資料庫db檔案就會自動建立,比如:
Connector.getDatabase();
操作資料
如果需要對某個表進行資料操作,需要讓其對應的javaBean類繼承DataSupport
public class Book extends DataSupport { //讓對應的類繼承DataSupport
...
}
接下來,進行新增資料的操作:
Book book = new Book();
book.setName("...");
book.setAuthor("...");
book.setPages(234);
book.setPrice(12,21);
book.setPress("unkow");
book.save(); //執行sava 就可以插入資料了
執行更新資料:
Book book = new Book();
book.setPrice(11.11);
book.setPress("Anchor");
book.updateAll("name = ? and authro = ?","..","...");
刪除資料:
DataSupport.deleteAll(Book.class, "price<?","13");
查詢資料:
//查詢所有
List<Book> books = DataSupport.findAll(Book.class);
// 查詢第一條
List<Book> books = DataSupport.findFirst(Book.class);
//查詢最後一條
List<Book> books = DataSupport.findLast(Book.class);
//查詢那幾列的資料
List<Book> books = DataSupport.select("name","author).find(Book.class);
//條件查詢, 頁面大於400
List<Book> books = DataSupport.where("pages >?","400").find(Book.class);
//將 price 降序排序
List<Book> books = DataSupport.order(price desc").find(Book.class);
//查詢前3條
List<Book> books = DataSupport.limit(3).find(Book.class);
//從下表1開始,往後查詢3條
List<Book> boods = DataSupport.limit(3).offset(1),find(Book.class)
當然這些方法也可以組合起來使用:
List<Book> books = DataSupport.select("name","author","pages")
.where("pages>?”,"400")
.order("pages")
.limit(10)
.offset(10)
.find(Book.class);
如果有些特殊查詢,使用上述方法無法查詢時,可以使用如下語句:
Cursor c = DataSupport.findBySQL("select * from Book where pages > ? and price < ?”,
"400","20”);
內容提供器(Conent Provider)方式
網路儲存方式
Android 六大布局
LinearLayout 線性佈局
線性佈局,如名字所描述的那樣,這個佈局將它所包含的控制元件線上性方向上一次排列,方向分為 水平方向和數值方向。
屬性 android:orientation = “vertical” | “horizontal” 豎直或水平,預設水平
屬性 android:layout_gravity = “top” | “center” | “bottom” 內部的佈局方式
屬性 android:gravity = “top”|"center”|“bottom” 相對於父容器的對齊方式
屬性 android:layout_weidht 使用比例方式執行控制元件的大小,在手機螢幕適配方面起到非常重要的作用