gpt4 book ai didi

android - 从 Internet 资源更新 ContentProvider 的底层 SQLite 数据库

转载 作者:行者123 更新时间:2023-11-29 00:30:46 24 4
gpt4 key购买 nike

我实现了一个 ContentProvider 来提供来自底层 SQLite 数据库的地理位置列表。

这些位置实际上是模型的输出,可以以简单的 JSON 字符串形式在线获取;我不想每次启动应用程序时都继续下载它们,所以我想将它们存储在本地数据库中并按预定义的时间间隔更新它们(例如每天一次)。

我的问题是,我应该在哪里实现下载和解析代码?它应该是我的 ContentProvider 实现的一部分吗?还是 SQLiteOpenHelper 实现的一部分?

我开始在我的 ContentProvider 中将它实现为一个名为 updateSiteList 的公共(public)函数,但我不知道如何实际调用它(通常间接访问 ContentProvider通过 CursorLoader)!

我对如何进步有点困惑!

谁能指出我正确的方向?

谢谢!

最佳答案

有几种方法可以实现这一点。我使用的两种最常用的方法是:-

1) 自定义同步适配器。

2) Intent 服务。

通过选项 1,您可以获得 Android 系统处理网络连接问题的好处,并且是 android 开发人员推荐的方法

使用选项 2,您可以更好地控制何时下载数据,这对于用户或 Android 系统来说可能是也可能不是最佳时间。

无论哪种方式,解决方案都是一样的。在某个时间点,您将在后台服务中向 url 发出 HTTP get 请求。当您的请求完成时,您将需要检查响应的状态,如果合适,您将调用内容提供商以相应地停止插入或更新您的数据。无论您采用哪种方法,这部分都是相同的。

一些进一步的阅读给你。 https://sites.google.com/site/andsamples/concept-of-syncadapter-androidcontentabstractthreadedsyncadapter

请务必观看 Google I/O 视频

无论您采用何种方法,下载 json 并插入到您的内容提供程序的代码在从您的同步适配器或您的应用程序中的某处(如果不使用同步适配器)调用的 IntentService 中可能看起来像这样。

public class ServiceInitialiseData extends IntentService {
static final String TAG = "ServiceSyncData";
//ACTION should include application package convention, just to show that this can
//be any string
public static final String SYNC_COMPLETED_ACTION="com.pjmobile.games.fantasyf1.SyncCompleted";

public ServiceInitialiseData() {
super("InitialiseDataService");
}

@Override
protected void onHandleIntent(Intent intent) {
String sJson;
try {
sJson = downloadFromServer("Some parsed url");
int i, x;
boolean res = false;
List <ContentValues> bulkValues = new ArrayList <ContentValues>();
JSONArray entries;
try {
entries = new JSONArray(sJson);
ContentValues cvEntity = null;
JSONObject entity;
x = entries.length();
for (i=0;i<x;i++){
entity = entries.getJSONObject(i).getJSONObject("some_json_key");
bulkValues.add(cvEntity);
}
}
int qCount = getContentResolver().bulkInsert(uri,
(ContentValues[])bulkValues.toArray(new
ContentValues[bulkValues.size()]));

} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


private String downloadFromServer(String url) throws ClientProtocolException, IOException {
HttpResponse sJson = getJSONEntityFromURL(this, url);
return EntityUtils.toString(sJson.getEntity());
}

private static HttpResponse getJSONEntityFromURL(Context context, String url) throws ClientProtocolException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
httpget.addHeader("Accept", "application/json");
httpget.addHeader("Content-Type", "application/json; charset=UTF-8");
HttpResponse response;

response = httpclient.execute(httpget);
return response;
}

要使上述工作正常,您必须优化您的内容提供程序的批量插入方法,它可能看起来像这样

    @Override
public int bulkInsert(Uri uri, ContentValues[] values) {
final SQLiteDatabase db = mDB.getWritableDatabase();
final int match = sURIMatcher.match(uri);
int numInserted= 0;
// Util.log_debug_message("@@@@ URI MATCH - " + match);
switch(match){
case TEAMS:
numInserted = insertTeams(db, values);
break;
default:
throw new UnsupportedOperationException("unsupported uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null, false);
return numInserted;
}

private int insertTeams(SQLiteDatabase db, ContentValues[] values) {
int numInserted = 0;
db.beginTransaction();
try {
//standard SQL insert statement, that can be reused
SQLiteStatement insert =
db.compileStatement(INSERT_OR_REPLACE_STRING + TeamModel.TEAM_TABLE_NAME
+ "(" + TeamModel.COL_SERVER_ID
+ "," + TeamModel.COL_BONUS_RACE_ID
+ "," + TeamModel.COL_POINTS
+ "," + TeamModel.COL_POSITION
+ "," + TeamModel.COL_TEAM_NAME + ")"
+" values " + "(?,?,?,?,?)");

for (ContentValues value : values){
//bind the 1-indexed ?'s to the values specified
insert.bindString(1, value.getAsString(TeamModel.COL_SERVER_ID));
insert.bindString(2, value.getAsString(TeamModel.COL_BONUS_RACE_ID));
insert.bindString(3, value.getAsString(TeamModel.COL_POINTS));
insert.bindString(4, value.getAsString(TeamModel.COL_POSITION));
insert.bindString(5, value.getAsString(TeamModel.COL_TEAM_NAME));
insert.execute();
}
db.setTransactionSuccessful();
numInserted = values.length;
} finally {
db.endTransaction();
db.close();
}
return numInserted;
}

这不是复制和粘贴解决方案。只是从我的一个应用程序中删除的一个示例,您应该查看每一行代码并非常小心地理解正在发生的事情。

关于android - 从 Internet 资源更新 ContentProvider 的底层 SQLite 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15886359/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com