我正在开发的应用程序在每次启动时从远程地址下载JSON文件,然后它解析JSON对象并将数据复制到手机上的SQLite。 此操作是应用程序在每个启动显示空白屏幕(或有时空白然后是黑屏)上挂起几秒钟的原因,事实上如果我尝试禁用这部分代码,应用程序可以快速启动,没有挂起。 那么,我怎么能做得更好呢?
以下是与文件下载,解析和写入本地SQLite db相关的代码(DataHandler类):
public class DataHandler {
public DataHandler() {
}
public int storeData(Database db, int num) throws JSONException {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.example.com/data.json");
request.addHeader("Cache-Control", "no-cache");
long id = -1;
try {
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStreamReader in = new InputStreamReader(entity.getContent());
BufferedReader reader = new BufferedReader(in);
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line=reader.readLine()) != null) {
stringBuilder.append(line);
}
JSONArray jsonArray = new JSONArray(stringBuilder.toString());
SQLiteDatabase dbWrite = db.getWritableDatabase();
ContentValues values = new ContentValues();
if (jsonArray.length() == num && num != 0)
return num;
SQLiteDatabase dbread = db.getReadableDatabase();
dbread.delete("mytable", "1", null);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jObj = (JSONObject) jsonArray.getJSONObject(i);
values.put("_id", jObj.optString("id").toString());
values.put("city", jObj.optString("city").toString());
values.put("country",jObj.optString("country").toString());
values.put("addr", jObj.optString("addr").toString());
values.put("title", jObj.optString("title").toString());
values.put("lon", jObj.optString("lon").toString());
values.put("email", jObj.optString("email").toString());
values.put("phone", jObj.optString("phone").toString());
values.put("web", jObj.optString("web").toString());
values.put("lat", jObj.optString("lat").toString());
values.put("desc", jObj.optString("desc").toString());
values.put("icon", jObj.optString("icon").toString());
values.put("category", jObj.optString("category").toString());
id = dbWrite.insert("merchants", null, values);
}
num = jsonArray.length();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (id > 0)
return num;
else
return -1;
}
}
答案 0 :(得分:0)
您可能应该在后台下载和解析,并在此期间显示某些带有进度信息的启动画面。 为了避免恼人的启动画面,您还可以在启动时正常缓存数据并显示应用程序,并且只有在bakground更新完成后才刷新数据。
有几种方法可以在后台执行下载和解析操作:
我不能说在您的具体情况下什么是最佳解决方案,但我建议您阅读Processes and Threads和service文档。
答案 1 :(得分:0)
她去你的异步任务类
class AsyncClass extends AsyncTask<String,Void,String>
{
int result;
Context context;
ProgressDialog bar;
AsynclassListener<String> listener;
public AsyncClass(Context context, AsynclassListener listener) {//add more parameter as your method body has (i.e Database db, int num) . Don't forget to initialize them.
this.context=context;
this.listener=listener;
bar = new ProgressDialog(context);
bar.setIndeterminate(false);
//make your progressBar here I have just given a simple example for above PB there are more parameters to set.
}
protected String doInBackground(String... Param){
try{
result = storeData();//call your method here
}catch(Exception e){
// Do something when crash
}
return ""+result;
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
bar.show();// By the time your data fetching and parsing will go on you this progress bar will be visible.
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
bar.dismiss();//As soon as the work is complete the this method is called.
listener.onTaskComplete(""+result);
/**
* In your case you can later typecast back in integer once you recieve the result.
* this listener will post the result to your main activity.
*/
}
}
这是您的界面
public interface AsynclassListener<T>{
public void onTaskComplete(T result);
}
现在让您的Activity(Splash Class)实现该接口 这将实现方法:
@Override
public void onTaskComplete(String result) {
// here the asynclass will post the result as 1 or -1 whatever you want.
//After that you may proceed with your next part i.e switching to next activity or so.
}
编辑:我忘了提及如何调用它:
new AsyncClass(getApplicationContext(), this).execute("");// here you have to enter the database and other parameter values that will be required to run the method. Change it accordingly.
正如您在方法中看到的那样,您从网络中获取数据并解析: 还有第二种方法,您可以在单独的线程中调用网络cal,稍后可以在UIthread上进一步解析。
还阅读有关异步任务类的信息,以便了解参数和类的工作情况。