編輯:關於Android編程
所謂外部數據庫文件此處指的就是一個在外部單獨創建的db文件,假設有這麼一個場景,我們項目中有一些本地數據,不需要接口去獲取的(不需要進行網絡操作),寫死的數據,比如全國各個省各個市的一些基本信息,每個市的信息可以作為表裡的一條記錄存放,在項目中使用,此時如何我們已經有了包含這些信息的db文件,我們就可以通過greendao來操作這個db文件,更具方便進行開發工作,當然這只是個模擬情況,至於合不合理,有沒有更好的方式,此處不過多討論,重點講這麼一種方式,這種方式可以用於一些不經常變化的數據。
res喎?/kf/ware/vc/" target="_blank" class="keylink">vcmF3xL/CvLTmt8W1xL7NysfN4rK/tcRkYs7EvP61xNG5y/XOxLz+o6zO0sPHv8nS1LTyv6q/tNK7z8LK/b7dv+K94bm5o6xkYs7EvP6w/Lqswb3VxbHto6xzdHVkZW50us10ZWFjaGVywO/D5rzytaW1xLLlyOvBy7y4zPWy4srUyv2+3aO6PC9wPg0KPHA+PGltZyBhbHQ9"這裡寫圖片描述" src="/uploadfile/Collfiles/20160714/201607140921281301.png" title="\" />
實現之前先說一下具體的思路,程序運行,首先把raw目錄下的db文件拷貝到數據庫存儲的默認目錄,然後通過greendao的api對這個文件進行操作即可;
我們需要獲取應用db存儲的路徑,通過如下方式:
private void getAppInfo()
{
// 獲取packageManager的實例
PackageManager packageManager = getPackageManager();
// getPackageName()是你當前類的包名,0代表是獲取版本信息
try
{
packInfo = packageManager.getPackageInfo(getPackageName(), 0);
}
catch (NameNotFoundException e)
{
e.printStackTrace();
}
}
通過以上方式即可獲取到數據庫的路徑:
拷貝操作:
public static boolean copyRawDBToApkDb(Context context, int copyRawDbResId, String apkDbPath, String dbName,boolean refresh)
throws IOException
{
boolean b = false;
File f = new File(apkDbPath);
if (!f.exists())
{
f.mkdirs();
}
File dbFile = new File(apkDbPath + dbName);
b = isDbFileExists(dbFile,refresh);
if (!b)
{
InputStream is = context.getResources().openRawResource(copyRawDbResId);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null)
{
int size;
byte[] buffer = new byte[1024 * 2];
OutputStream fos = new FileOutputStream(apkDbPath + entry.getName());
BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);
while ((size = zis.read(buffer, 0, buffer.length)) != -1)
{
bos.write(buffer, 0, size);
}
bos.flush();
bos.close();
}
zis.close();
is.close();
}
return !b;
}
此處是拷貝操作的關鍵代碼,需要我們傳入raw資源ID,數據庫的拷貝路徑,數據庫文件名,是否覆蓋已經存在的db文件,@return 拷貝是否成功,關於refresh參數,我們一般希望只拷貝一次,當我們在某些情況下更新了這個db文件的話就可以設置為true進行覆蓋操作;
使用greenDao java工程,生成外部db文件所對應表的實體類Dao類等代碼:上圖中的DBController類是我封裝的數據庫操作類,更方便我們去進行操作,DBController的關鍵代碼如下:
/**
* 外部數據庫控制類
*/
public class DBController
{
private static DaoMaster daoMasterEcmc;
private static DaoMaster daoMasterSchool;
// 默認DB
private static DaoSession daoSessionDefault;
// 拷貝的db
private static DaoSession daoSchoolSession;
/**
* 默認數據庫名稱:localdata
*/
public static final String DATABASE_NAME = "localdata.db";
/**
* 拷貝數據庫名稱:school
*/
public static final String DATABASE_SCHOOL_NAME = "school.db";
private static DaoMaster obtainMaster(Context context, String dbName)
{
return new DaoMaster(new DaoMaster.DevOpenHelper(context, dbName, null).getWritableDatabase());
}
private static DaoMaster getDaoMaster(Context context, String dbName)
{
if (dbName == null)
return null;
if (daoMasterEcmc == null)
{
daoMasterEcmc = obtainMaster(context, dbName);
}
return daoMasterEcmc;
}
private static DaoMaster getSchoolDaoMaster(Context context, String dbName)
{
if (dbName == null)
return null;
if (daoMasterSchool == null)
{
daoMasterSchool = obtainMaster(context, dbName);
}
return daoMasterSchool;
}
/**
* 取得DaoSession
*
* @return
*/
public static DaoSession getDaoSession(String dbName)
{
if (daoSchoolSession == null)
{
daoSchoolSession = getSchoolDaoMaster(MainApplication.getIns(), dbName).newSession();
}
return daoSchoolSession;
}
/**
* 默認操作localdata數據庫
*/
public static DaoSession getDaoSession()
{
if (daoSessionDefault == null)
{
daoSessionDefault = getDaoMaster(MainApplication.getIns(), DATABASE_NAME).newSession();
}
return daoSessionDefault;
}
}
可能我們還需要默認的greendao數據庫進行其他的操作,至於默認的操作此處不再詳細介紹,不了解的可以看greendao基本使用,此處我們演示的外部DB文件命名為school.db,默認的greenDao數據庫命名為history.db,下面我們在MainActivity進行測試操作:
public class MainActivity extends Activity
{
private StringBuilder builder;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//創建默認的數據,並插入一條數據
HistoryDao historyDao = DBLocalController.getDaoSession().getHistoryDao();
History entity = new History();
entity.setName("科羅拉多");
entity.setImageUrl("http://www.baidu.com");
historyDao.insert(entity);
//拷貝外部DB文件到指定目錄
copyRawDB();
//通過greendao查詢外部db文件數據
selDBData();
}
private void selDBData()
{
StudentDao student = DBController.getDaoSession(DBController.DATABASE_SCHOOL_NAME).getStudentDao();
List students = student.queryBuilder().list();
builder = new StringBuilder();
for (int i = 0; i < students.size(); i++)
{
builder.append(students.get(i).getName() + "---");
}
Toast.makeText(MainActivity.this, builder.toString(), Toast.LENGTH_SHORT).show();
}
private void copyRawDB()
{
try
{
// 拷貝res/raw/xxxxdb.zip 到
// /data/data/com.xinhang.mobileclient/databases/ 目錄下面
boolean isSuccess = DBUtils.copyRawDBToApkDb(MainActivity.this, R.raw.schooldb, DBUtils.APK_DB_PATH, DBUtils.ECMC_DB_NAME, false);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
運行結果:
可以看到我們的外部db文件已經拷貝到數據庫默認路徑下,還有我們的默認數據庫也創建成功;區分兩個數據庫的方式是通過DBLocalController.getDaoSession(name)方法,想操作哪個數據庫傳入對應的數據庫名稱即可,gif操作圖如下;
源碼下載:源碼下載,有問題歡迎交流討論!
在Android中,如果我們需要在不同進程間實現通信,就需要用到AIDL技術去完成。AIDL(Android Interface Definition Language)
本文為那些不錯的Android開源項目第三篇——優秀項目篇,主要介紹那些還不錯的完整Android項目。記錄的項目主要依據是項目有意思或項目分層規
最近在做APP,需要監聽Android手機網絡的變化情況,同時對不同的情況做出不同的響應策略,這裡有兩種方法。判斷聯網工具類這裡我使用的是ConnectivityMan
前言ScrollView可以說是android裡最簡單的滑動控件,但是其中也蘊含了很多的知識點。今天嘗試通過ScrollView的源碼來了解ScrollView內部的細節