0

因此,我正在編寫一個應用程序,它在第一次運行時需要從Web中拉出一些數據並將其寫入數據庫表。問題是它崩潰了UI線程。它運行在異步任務中,但仍然在UI上引發問題。我並不關心進度或知道何時完成。只是希望它在沒有用戶真正瞭解的情況下做到這一點。Android在異步任務中執行大的sqllite寫入會凍結UI

它不是一噸數據。 JSON響應低於600kb,在DB中大約有9000行。只需要大約30-45秒,但我寧願讓該應用的其餘部分在那段時間內可用。

這裏是我有一些設置來建立一個異步任務中的數據庫。

public void updateDBBackground() { 
    new UpdateDbTask().execute("", "", ""); 
} 


private class UpdateDbTask extends AsyncTask<String, String, String> { 
    protected String doInBackground(String... urls) { 
     long totalSize = 0; 
     open(); 
     String url = "someurl"; 

     JsonObjectRequest jsObjRequest = new JsonObjectRequest 
       (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { 

        @Override 
        public void onResponse(JSONObject response) { 
         try { 
          JSONArray queuearray = response.getJSONArray("items"); 
          for (int i = 0; i < queuearray.length(); i++) { 
           if (!queuearray.getJSONObject(i).getString("artist").isEmpty()) { 
            insert(queuearray.getJSONObject(i).getLong("id"), queuearray.getJSONObject(i).getString("item1"), queuearray.getJSONObject(i).getString("item2")); 
           } 
          } 

         } catch (Exception e) { 

         } 
        } 
       }, new Response.ErrorListener() { 

        @Override 
        public void onErrorResponse(VolleyError error) { 


        } 
       }); 

     VolleySig.getInstance(context).addToRequestQueue(jsObjRequest); 

     return ""; 
    } 

    protected void onProgressUpdate(String... progress) { 
    } 

    protected void onPostExecute(String result) { 
    } 
} 

我從主要活動中調用所有這些。

DBManager db = new DBManager(this); 
    if (!db.checkDb()) { 
     db.updateDBBackground(); 
    } 

這裏是崩潰報告數據。

09-04 17:20:29.065 18263-18270/com.SOMEAPP I/art: Thread[3,tid=18270,WaitingInMainSignalCatcherLoop,Thread*=0x7a74799000,peer=0x12ccb160,"Signal Catcher"]: reacting to signal 3 
09-04 17:20:29.155 18263-18270/com.SOMEAPP I/art: Wrote stack traces to '/data/anr/traces.txt' 

這裏是traces.txt的內容

http://pastebin.com/traces

+0

請問你能粘貼崩潰轉儲嗎? – dex

+0

這是一個很好的使用服務的用例,你的任務沒有理由在Activity中運行。 – Egor

+0

添加了相關的崩潰數據。我想過使用一項服務。似乎有一點一次的事情。所以它從一個活動開始,因爲這只是應用程序的第一件事。打開它,去家裏的活動。 – Dandrews

回答

0

原來這是做的項目在後臺線程,但產卵夠了他們,這是造成UI掛起。

由於幾個原因,我將數據庫從Sqllite切換到了Realm,並且現在正在將項目加載爲show。有時可能會有一兩個UI滯後,但沒有太大意義。

private void UpdateDB() { 
    String url = "http://example.com&return=JSON"; 

    JsonObjectRequest jsObjRequest = new JsonObjectRequest 
      (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { 

       @Override 
       public void onResponse(JSONObject response) { 
        try { 
         final JSONArray queuearray = response.getJSONArray("items"); 

         realmConfig = new RealmConfiguration.Builder(getApplicationContext()).build(); 
         // Open the Realm for the UI thread. 
         realm = Realm.getInstance(realmConfig); 


         realm.executeTransaction(new Realm.Transaction() { 
          @Override 
          public void execute(Realm realm) { 
           // Add a person 

           for (int i = 0; i < queuearray.length(); i++) { 

            try { 
             if (!queuearray.getJSONObject(i).getString("value").isEmpty()) { 
              Media media = realm.createObject(Media.class); 
              media.setValue(queuearray.getJSONObject(i).getString("value")); 
              media.setTitle(queuearray.getJSONObject(i).getString("title")); 
              media.setItemid(queuearray.getJSONObject(i).getLong("itemid")); 
             } 
            } catch (Exception e) { 

            } 
           } 

          } 
         }); 


        } catch (Exception e) { 


        } 
       } 
      }, new Response.ErrorListener() { 

       @Override 
       public void onErrorResponse(VolleyError error) { 

       } 
      }); 

    VolleySig.getInstance(this).addToRequestQueue(jsObjRequest); 

    realm.close(); 
}