2013-02-03 20 views
0

我有一個應用程序,當您加載它時,它會顯示6個按鈕。第6個按鈕需要可視化一些數據。該數據以JSON格式保存在我的/raw文件夾中的txt文件中。數據大小爲600kb,但目前需要大約3分鐘才能解析並存儲在數據庫中。這個想法是,一旦它在數據庫中,讀取和使用數據的效率和速度都會更快,而不是每次都直接從文件中讀取數據。Android - 首次運行時解析文件時需要的一般建議

我最初製作的應用程序是爲了從我的REST服務器下載數據,然後將其存儲在數據庫中,但後來發現只要將該文件與應用程序一起發送,就會快得多。但是,它仍然很慢。

我在尋找關於如何加快這個文件解析並改善用戶體驗的建議。目前,他們第一次進入本節時,會出現一個ProgressDialog,他們必須等待幾分鐘(我的HTC Desire上3分鐘)才能使用該功能,然後才能完成所有此文件解析。進度對話框就在那裏,一直工作直到完成,用戶無法做其他事情。它不理想! 我曾考慮過在後臺的單獨線程中在應用程序的開始處運行文件處理,而沒有進度條,因此它對用戶來說顯得很沉默,但是,如果他們選擇了進入該部分的按鈕在應用程序加載完成後立即依賴這些數據,那麼它將導致更多問題,因爲文件處理可能尚未完成。

也許我可以添加一些帶有大量文本的「指令性」彈出框,這樣當他們讀完文件時,文件處理就完成了。不過,我不確定該應用增加了什麼價值。它非常簡單易用!

任何人都可以給我一個更好的策略建議嗎?另外,我是否認爲3分鐘解析JSON的600kb有點過長?也許我的邏輯並不像應該那樣高效。

這裏是線程的開始:

private boolean parseFile() { 
    dialog = ProgressDialog.show(activity, 
      "Progress Title", 
      "Progress body", 
      true); 
    ReadDataThread unt = new ReadDataThread(); 
    unt.start(); 
    return true; 
} 

private class ReadDataThread extends Thread { 
    @Override 
    public void run() { 
     InputStream is = activity.getResources().openRawResource(R.raw.dbdata); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
     try { 
      StringBuilder sb = new StringBuilder(); 
      sb.append(reader.readLine()); 
      sortAndStore(sb.toString()); 
     } catch (IOException e) { 
      Log.e(Constants.TAG, "Error reading data"); 
      e.printStackTrace(); 
     } 
     handler.sendEmptyMessage(0); 
    } 

    private final Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      if (dialog.isShowing()) 
       dialog.dismiss(); 
      Toast.makeText(activity, "Finished reading data", Toast.LENGTH_SHORT).show(); 
     } 
    }; 
} 

你會發現,它調用了一個名爲sortAndStore方法,它是在這裏:

@Override 
public boolean sortAndStore(String raw) { 
    boolean returnCode=false; 
    ContentValues initialValues = new ContentValues(); 

    try { 
     JSONObject f = new JSONObject(raw); 
     JSONArray jsonArr = f.getJSONArray("stops"); 
     int arrSize=jsonArr.length(); 
     for(int i=0; i<arrSize; i++) {    
      initialValues.put("name", jsonArr.getJSONObject(i).getString("name")); 
      initialValues.put("lat", jsonArr.getJSONObject(i).getString("lat")); 
      initialValues.put("lng", jsonArr.getJSONObject(i).getString("lng")); 
      initialValues.put("StopNumber", jsonArr.getJSONObject(i).getString("StopNumber")); 
      initialValues.put("Route", jsonArr.getJSONObject(i).getString("Route")); 
      initialValues.put("Type", jsonArr.getJSONObject(i).getString("Type")); 

      //Add data to DB 
      DBHelper db = new DBHelper(activity); 
      returnCode = db.addData(initialValues, DBHelper.DBTableName); 
     } 
    } catch (JSONException e) { 
     returnCode=false; 
     e.printStackTrace(); 
    } 
    return returnCode; 
} 

我還用叫DBHelper一個DatabaseHelper類處理數據庫的東西。該DBHelper.addData()方法是在這裏:

public boolean addData(ContentValues initialValues, String tableName) { 
    openDatabase(); 
    long returnCode = db.insert(tableName, "ID", initialValues); 
    closeDatabase(); 
    return (returnCode == -1 ? false:true); 
} 

所以,任何人都可以提出這個更好的策略,基於上述數據?要麼是更高效的文件I/O代碼,要麼是一些用戶界面技巧,讓用戶覺得處理所花費的時間比實際所需的時間更少?

謝謝。

+0

如何預加載數據庫中的數據並將其與您的應用程序一起發貨? – Rajesh

+0

我同意@Rajesh對於固定數據,這也是我想的最好的方式。 – lulumeya

+0

嗨Rajesh。我不知道你可以用你的應用發佈一個人口稠密的數據庫,因此我爲什麼要這樣做。如果那是真的,那顯然是最好的選擇。我會進一步研究,看看它是否可能。 – eoinzy

回答

0

我通過簡單地使用statements而不是單獨的insert語句來解決此問題。

例如,在for()循環之前,我得到了數據庫並開始了事務。然後我像往常一樣經歷循環。在循環之後,我只是關閉了交易,從而實現了批量交易。

插入現在需要幾秒鐘!

0

我想你可以展示固定面積的進展,如角落裏的某個角落,比如動作欄等等。進度可能會在你的應用中顯示全局進度。然後用戶將知道正在進行的工作,並且您可以讓用戶在沒有您的數據的情況下執行某些操作。