android文件管理器用法詳解
很久沒有寫東西了,鑒于某某同學(xué)文件管理器不會,這里簡單介紹一下,同時寫一個demon,參考了網(wǎng)上別人寫的代碼,自己也學(xué)習(xí)學(xué)習(xí),研究研究。
首先所謂文件管理器,看起來就是一個列表,列表里面是文件夾或者文件,首先把布局寫出來,我想在最上方的左邊顯示文件的路徑,右邊顯示該路徑下的文件個數(shù),其實還是一個遍歷文件,然后用列表顯示出來的問題。下面是ListView,用來顯示文件列表。下面是運行的效果圖:

主界面的布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:textSize="@*android:dimen/list_item_size"
android:textColor="@android:color/white"/>
<TextView
android:id="@+id/item_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@*android:dimen/list_item_size"
android:textColor="@android:color/white"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dip"
android:background="#09c"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/file_list"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fadingEdge="none"
android:cacheColorHint="@android:color/transparent"/>
</LinearLayout>
</LinearLayout>
首先在oncreate方法里面調(diào)用一個方法去獲取布局文件里面的id:
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_manager);
initView();
}
initView之后添加apk的權(quán)限,777 表示可讀可寫可操作。
private void initView() {
mListView = (ListView) findViewById(R.id.file_list);
mPathView = (TextView) findViewById(R.id.path);
mItemCount = (TextView) findViewById(R.id.item_count);
mListView.setOnItemClickListener(this);
String apkRoot = "chmod 777 " + getPackageCodePath();
RootCommand(apkRoot);
File folder = new File("/");
initData(folder);
}
修改Root權(quán)限的方法:
public static boolean RootCommand (String command) {
Process process = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
}
catch (Exception e) {
return false;
}
finally {
try {
if (os != null) {
os.close();
}
process.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
完了之后我們要獲取根目錄下面的所有的數(shù)據(jù),然后設(shè)置到我們的ListView中讓它顯示出來。
private void initData(File folder) {
boolean isRoot = folder.getParent() == null;
mPathView.setText(folder.getAbsolutePath());
ArrayList<File> files = new ArrayList<File>();
if (!isRoot) {
files.add(folder.getParentFile());
}
File[] filterFiles = folder.listFiles();
mItemCount.setText(filterFiles.length + "項");
if (null != filterFiles && filterFiles.length > 0) {
for (File file : filterFiles) {
files.add(file);
}
}
mFileAdpter = new FileListAdapter(this, files, isRoot);
mListView.setAdapter(mFileAdpter);
}
首先是獲取當(dāng)前是否是根目錄,然后把文件的路徑設(shè)置給我們要顯示的View。
然后用一個ArrayList來裝我們目錄下的所有的文件或者文件夾。
首先要把這個文件夾的父類裝到我們的列表中去,然后把這個文件夾下的子文件都拿到,也裝在列表中,然后調(diào)用Adapter顯示出來。既然說到了Adapter, 那就看下Adapter吧。
private class FileListAdapter extends BaseAdapter {
private Context context;
private ArrayList<File> files;
private boolean isRoot;
private LayoutInflater mInflater;
public FileListAdapter (Context context, ArrayList<File> files, boolean isRoot) {
this.context = context;
this.files = files;
this.isRoot = isRoot;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount () {
return files.size();
}
@Override
public Object getItem (int position) {
return files.get(position);
}
@Override
public long getItemId (int position) {
return position;
}
@Override
public View getView (int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.file_list_item, null);
convertView.setTag(viewHolder);
viewHolder.title = (TextView) convertView.findViewById(R.id.file_title);
viewHolder.type = (TextView) convertView.findViewById(R.id.file_type);
viewHolder.data = (TextView) convertView.findViewById(R.id.file_date);
viewHolder.size = (TextView) convertView.findViewById(R.id.file_size);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
File file = (File) getItem(position);
if(position == 0 && !isRoot) {
viewHolder.title.setText("返回上一級");
viewHolder.data.setVisibility(View.GONE);
viewHolder.size.setVisibility(View.GONE);
viewHolder.type.setVisibility(View.GONE);
} else {
String fileName = file.getName();
viewHolder.title.setText(fileName);
if(file.isDirectory()) {
viewHolder.size.setText("文件夾");
viewHolder.size.setTextColor(Color.RED);
viewHolder.type.setVisibility(View.GONE);
viewHolder.data.setVisibility(View.GONE);
} else {
long fileSize = file.length();
if(fileSize > 1024*1024) {
float size = fileSize /(1024f*1024f);
viewHolder.size.setText(new DecimalFormat("#.00").format(size) + "MB");
} else if(fileSize >= 1024) {
float size = fileSize/1024;
viewHolder.size.setText(new DecimalFormat("#.00").format(size) + "KB");
} else {
viewHolder.size.setText(fileSize + "B");
}
int dot = fileName.indexOf('.');
if(dot > -1 && dot < (fileName.length() -1)) {
viewHolder.type.setText(fileName.substring(dot + 1) + "文件");
}
viewHolder.data.setText(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(file.lastModified()));
}
}
return convertView;
}
class ViewHolder {
private TextView title;
private TextView type;
private TextView data;
private TextView size;
}
}
看下adapter的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/file_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="#fff000"/>
<LinearLayout
android:id="@+id/file_info"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/file_size"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:textColor="#ffffcc"
android:layout_weight="1"
android:textSize="18sp"/>
<TextView
android:id="@+id/file_type"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:textColor="#ffffcc"
android:layout_weight="1"
android:gravity="right"
android:textSize="18sp"/>
<TextView
android:id="@+id/file_date"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:layout_weight="1"
android:gravity="right"
android:textSize="18sp"/>
</LinearLayout>
</LinearLayout>
列表的Item項分2行顯示,上面一行顯示文件名
下面一行分別顯示文件大小,文件類型,文件修改時間。
我們可以通過File file = (File) getItem(position);拿到Item項的文件,如果是在第一個并且不再根目錄我們就把第一個也就是parentFile顯示為:“返回上一級”,下一行的都隱藏掉。
如果不是第一個位置,可以拿到這個文件的一系列信息。
先把String fileName = file.getName();文件名拿到,顯示出來。
如果這個文件是一個文件夾,就把文件的大小顯示為“文件夾”,類型和修改時間隱藏掉。
如果不是一個文件夾, 可以拿到文件的長度long fileSize = file.length();
根據(jù)特定的長度顯示文件的大小,B, KB, MB, GB等。
然后拿到文件的類型,通過最后一個“.”之后的字符串就是該文件的類型。
通過viewHolder.data.setText(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(file.lastModified())); 設(shè)置文件的最近修改時間。
然后可以設(shè)置每個Item項的點擊事件,如下所示:
@Override
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
File file = (File) mFileAdpter.getItem(position);
if(!file.canRead()) {
new AlertDialog.Builder(this).setTitle("提示").setMessage("權(quán)限不足").setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick (DialogInterface dialog, int which) {
}
}).show();
} else if(file.isDirectory()) {
initData(file);
} else {
openFile(file);
}
}
如果這個文件不能讀,就彈出對話框顯示“權(quán)限不足”。
如果是一個文件夾,就在調(diào)用一次顯示所有文件的方法:initData(file);把這個文件夾作為參數(shù)傳遞下去。
如果是一個文件,就可以調(diào)用打開文件的方法打開這個文件。
如何打開文件呢?
可以根據(jù)不同的文件的后綴名找到不同的文件類型:
可以用一個二維數(shù)組把一些常用的文件類型封裝起來。如下:
private final String[][] MIME_MapTable = {
// {后綴名, MIME類型}
{ ".3gp", "video/3gpp" },
{ ".apk", "application/vnd.android.package-archive" },
{ ".asf", "video/x-ms-asf" },
{ ".avi", "video/x-msvideo" },
{ ".bin", "application/octet-stream" },
{ ".bmp", "image/bmp" },
{ ".c", "text/plain" },
{ ".class", "application/octet-stream" },
{ ".conf", "text/plain" },
{ ".cpp", "text/plain" },
{ ".doc", "application/msword" },
{ ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
{ ".xls", "application/vnd.ms-excel" },
{ ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
{ ".exe", "application/octet-stream" },
{ ".gif", "image/gif" },
{ ".gtar", "application/x-gtar" },
{ ".gz", "application/x-gzip" },
{ ".h", "text/plain" },
{ ".htm", "text/html" },
{ ".html", "text/html" },
{ ".jar", "application/java-archive" },
{ ".java", "text/plain" },
{ ".jpeg", "image/jpeg" },
{ ".jpg", "image/jpeg" },
{ ".js", "application/x-javascript" },
{ ".log", "text/plain" },
{ ".m3u", "audio/x-mpegurl" },
{ ".m4a", "audio/mp4a-latm" },
{ ".m4b", "audio/mp4a-latm" },
{ ".m4p", "audio/mp4a-latm" },
{ ".m4u", "video/vnd.mpegurl" },
{ ".m4v", "video/x-m4v" },
{ ".mov", "video/quicktime" },
{ ".mp2", "audio/x-mpeg" },
{ ".mp3", "audio/x-mpeg" },
{ ".mp4", "video/mp4" },
{ ".mpc", "application/vnd.mpohun.certificate" },
{ ".mpe", "video/mpeg" },
{ ".mpeg", "video/mpeg" },
{ ".mpg", "video/mpeg" },
{ ".mpg4", "video/mp4" },
{ ".mpga", "audio/mpeg" },
{ ".msg", "application/vnd.ms-outlook" },
{ ".ogg", "audio/ogg" },
{ ".pdf", "application/pdf" },
{ ".png", "image/png" },
{ ".pps", "application/vnd.ms-powerpoint" },
{ ".ppt", "application/vnd.ms-powerpoint" },
{ ".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
{ ".prop", "text/plain" },
{ ".rc", "text/plain" },
{ ".rmvb", "audio/x-pn-realaudio" },
{ ".rtf", "application/rtf" },
{ ".sh", "text/plain" },
{ ".tar", "application/x-tar" },
{ ".tgz", "application/x-compressed" },
{ ".txt", "text/plain" },
{ ".wav", "audio/x-wav" },
{ ".wma", "audio/x-ms-wma" },
{ ".wmv", "audio/x-ms-wmv" },
{ ".wps", "application/vnd.ms-works" },
{ ".xml", "text/plain" },
{ ".z", "application/x-compress" },
{ ".zip", "application/x-zip-compressed" },
{ "", "*/*" }
};
分別對應(yīng)的是后綴名和對應(yīng)的文件類型。
我們可以根據(jù)文件的后綴名拿到文件的MIMEType類型:
private String getMIMEType(File file) {
String type = "*/*";
String fileName = file.getName();
int dotIndex = fileName.indexOf('.');
if(dotIndex < 0) {
return type;
}
String end = fileName.substring(dotIndex, fileName.length()).toLowerCase();
if(end == "") {
return type;
}
for(int i=0; i<MIME_MapTable.length; i++) {
if(end == MIME_MapTable[i][0]) {
type = MIME_MapTable[i][1] ;
}
}
return type;
}
先遍歷后綴名,如果找到,就把對應(yīng)的類型找到并返回。
拿到了類型,就可以打開這個文件。
用這個intent.setDataAndType(Uri.fromFile(file), type); 打開設(shè)置打開文件的類型。
如果type是*/*會彈出所有的可供選擇的應(yīng)用程序。
到這里一個簡易的文件管理器就成型了。
源代碼:
package com.android.test;
import java.io.DataOutputStream;
import java.io.File;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class FileManager extends Activity implements OnItemClickListener {
private ListView mListView;
private TextView mPathView;
private FileListAdapter mFileAdpter;
private TextView mItemCount;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_manager);
initView();
}
private void initView() {
mListView = (ListView) findViewById(R.id.file_list);
mPathView = (TextView) findViewById(R.id.path);
mItemCount = (TextView) findViewById(R.id.item_count);
mListView.setOnItemClickListener(this);
String apkRoot = "chmod 777 " + getPackageCodePath();
RootCommand(apkRoot);
File folder = new File("/");
initData(folder);
}
public static boolean RootCommand (String command) {
Process process = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
}
catch (Exception e) {
return false;
}
finally {
try {
if (os != null) {
os.close();
}
process.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
private void initData(File folder) {
boolean isRoot = folder.getParent() == null;
mPathView.setText(folder.getAbsolutePath());
ArrayList<File> files = new ArrayList<File>();
if (!isRoot) {
files.add(folder.getParentFile());
}
File[] filterFiles = folder.listFiles();
mItemCount.setText(filterFiles.length + "項");
if (null != filterFiles && filterFiles.length > 0) {
for (File file : filterFiles) {
files.add(file);
}
}
mFileAdpter = new FileListAdapter(this, files, isRoot);
mListView.setAdapter(mFileAdpter);
}
private class FileListAdapter extends BaseAdapter {
private Context context;
private ArrayList<File> files;
private boolean isRoot;
private LayoutInflater mInflater;
public FileListAdapter (Context context, ArrayList<File> files, boolean isRoot) {
this.context = context;
this.files = files;
this.isRoot = isRoot;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount () {
return files.size();
}
@Override
public Object getItem (int position) {
return files.get(position);
}
@Override
public long getItemId (int position) {
return position;
}
@Override
public View getView (int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.file_list_item, null);
convertView.setTag(viewHolder);
viewHolder.title = (TextView) convertView.findViewById(R.id.file_title);
viewHolder.type = (TextView) convertView.findViewById(R.id.file_type);
viewHolder.data = (TextView) convertView.findViewById(R.id.file_date);
viewHolder.size = (TextView) convertView.findViewById(R.id.file_size);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
File file = (File) getItem(position);
if(position == 0 && !isRoot) {
viewHolder.title.setText("返回上一級");
viewHolder.data.setVisibility(View.GONE);
viewHolder.size.setVisibility(View.GONE);
viewHolder.type.setVisibility(View.GONE);
} else {
String fileName = file.getName();
viewHolder.title.setText(fileName);
if(file.isDirectory()) {
viewHolder.size.setText("文件夾");
viewHolder.size.setTextColor(Color.RED);
viewHolder.type.setVisibility(View.GONE);
viewHolder.data.setVisibility(View.GONE);
} else {
long fileSize = file.length();
if(fileSize > 1024*1024) {
float size = fileSize /(1024f*1024f);
viewHolder.size.setText(new DecimalFormat("#.00").format(size) + "MB");
} else if(fileSize >= 1024) {
float size = fileSize/1024;
viewHolder.size.setText(new DecimalFormat("#.00").format(size) + "KB");
} else {
viewHolder.size.setText(fileSize + "B");
}
int dot = fileName.indexOf('.');
if(dot > -1 && dot < (fileName.length() -1)) {
viewHolder.type.setText(fileName.substring(dot + 1) + "文件");
}
viewHolder.data.setText(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(file.lastModified()));
}
}
return convertView;
}
class ViewHolder {
private TextView title;
private TextView type;
private TextView data;
private TextView size;
}
}
@Override
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
File file = (File) mFileAdpter.getItem(position);
if(!file.canRead()) {
new AlertDialog.Builder(this).setTitle("提示").setMessage("權(quán)限不足").setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick (DialogInterface dialog, int which) {
}
}).show();
} else if(file.isDirectory()) {
initData(file);
} else {
openFile(file);
}
}
private void openFile(File file) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = getMIMEType(file);
intent.setDataAndType(Uri.fromFile(file), type);
try {
startActivity(intent);
}
catch (Exception e) {
Toast.makeText(this, "未知類型,不能打開", Toast.LENGTH_SHORT).show();
}
}
private String getMIMEType(File file) {
String type = "*/*";
String fileName = file.getName();
int dotIndex = fileName.indexOf('.');
if(dotIndex < 0) {
return type;
}
String end = fileName.substring(dotIndex, fileName.length()).toLowerCase();
if(end == "") {
return type;
}
for(int i=0; i<MIME_MapTable.length; i++) {
if(end == MIME_MapTable[i][0]) {
type = MIME_MapTable[i][1] ;
}
}
return type;
}
private final String[][] MIME_MapTable = {
// {后綴名, MIME類型}
{ ".3gp", "video/3gpp" },
{ ".apk", "application/vnd.android.package-archive" },
{ ".asf", "video/x-ms-asf" },
{ ".avi", "video/x-msvideo" },
{ ".bin", "application/octet-stream" },
{ ".bmp", "image/bmp" },
{ ".c", "text/plain" },
{ ".class", "application/octet-stream" },
{ ".conf", "text/plain" },
{ ".cpp", "text/plain" },
{ ".doc", "application/msword" },
{ ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
{ ".xls", "application/vnd.ms-excel" },
{ ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
{ ".exe", "application/octet-stream" },
{ ".gif", "image/gif" },
{ ".gtar", "application/x-gtar" },
{ ".gz", "application/x-gzip" },
{ ".h", "text/plain" },
{ ".htm", "text/html" },
{ ".html", "text/html" },
{ ".jar", "application/java-archive" },
{ ".java", "text/plain" },
{ ".jpeg", "image/jpeg" },
{ ".jpg", "image/jpeg" },
{ ".js", "application/x-javascript" },
{ ".log", "text/plain" },
{ ".m3u", "audio/x-mpegurl" },
{ ".m4a", "audio/mp4a-latm" },
{ ".m4b", "audio/mp4a-latm" },
{ ".m4p", "audio/mp4a-latm" },
{ ".m4u", "video/vnd.mpegurl" },
{ ".m4v", "video/x-m4v" },
{ ".mov", "video/quicktime" },
{ ".mp2", "audio/x-mpeg" },
{ ".mp3", "audio/x-mpeg" },
{ ".mp4", "video/mp4" },
{ ".mpc", "application/vnd.mpohun.certificate" },
{ ".mpe", "video/mpeg" },
{ ".mpeg", "video/mpeg" },
{ ".mpg", "video/mpeg" },
{ ".mpg4", "video/mp4" },
{ ".mpga", "audio/mpeg" },
{ ".msg", "application/vnd.ms-outlook" },
{ ".ogg", "audio/ogg" },
{ ".pdf", "application/pdf" },
{ ".png", "image/png" },
{ ".pps", "application/vnd.ms-powerpoint" },
{ ".ppt", "application/vnd.ms-powerpoint" },
{ ".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
{ ".prop", "text/plain" },
{ ".rc", "text/plain" },
{ ".rmvb", "audio/x-pn-realaudio" },
{ ".rtf", "application/rtf" },
{ ".sh", "text/plain" },
{ ".tar", "application/x-tar" },
{ ".tgz", "application/x-compressed" },
{ ".txt", "text/plain" },
{ ".wav", "audio/x-wav" },
{ ".wma", "audio/x-ms-wma" },
{ ".wmv", "audio/x-ms-wmv" },
{ ".wps", "application/vnd.ms-works" },
{ ".xml", "text/plain" },
{ ".z", "application/x-compress" },
{ ".zip", "application/x-zip-compressed" },
{ "", "*/*" }
};
}
最后補充一下,布局文件中的dimension是編譯到j(luò)ar包里面去了的,沒有jar包的童鞋可以改成自己定義大小。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開發(fā)中總結(jié)的Adapter工具類【附完整源碼下載】
這篇文章主要介紹了Android開發(fā)中總結(jié)的Adapter工具類,簡單說明了Adapter的功能,并結(jié)合實例形式分析了Adapter工具類的相關(guān)使用方法,并附帶完整源碼供讀者下載參考,需要的朋友可以參考下2017-11-11
Kotlin+buildSrc更好的管理Gradle依賴譯文
這篇文章主要為大家介紹了Kotlin+buildSrc更好的管理Gradle依賴譯文及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
解決android viewmodel 數(shù)據(jù)刷新異常的問題
這篇文章主要介紹了解決android viewmodel 數(shù)據(jù)刷新異常的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android開發(fā)之使用SQLite存儲數(shù)據(jù)的方法分析
這篇文章主要介紹了Android開發(fā)之使用SQLite存儲數(shù)據(jù)的方法,結(jié)合實例形式分析了Android使用SQLite數(shù)據(jù)庫實現(xiàn)針對數(shù)據(jù)的增刪改查操作相關(guān)技巧,需要的朋友可以參考下2017-07-07

