2015-11-30 1 views
0

lorsque j'exécute mon application dans Android Studio, tout fonctionne correctement. Le ListView dans le tiroir est correctement rempli en exécutant une requête RushSearch(). Mais quand j'ai créé l'apk et que je l'ai installé sur mon smartphone pour essayer d'exécuter l'application, le ListView in Drawer à la première exécution n'est pas rempli. Si je ferme l'application et la réexécute, tout est correct.Erreur lors de l'exécution de l'application sur mon smartphone, mais c'est correct Si je lance l'application sur Android Studio

Pourquoi cette anomalie?

Le code pour la méthode de la classe onCreate MainActivity.java est ce

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    callWebservice(); 

    // Layout principale col drawer 
    setContentView(R.layout.activity_main_drawer); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
    leftArrow = (ImageView) findViewById(R.id.left_arrow); 
    titolo = (TextView) findViewById(R.id.titolo_id); 

    ActionBarDrawerToggle actionBarDrawerToggle = 
      new ActionBarDrawerToggle(this, drawerLayout, toolbar, 
        R.string.navigation_drawer_open, R.string.navigation_drawer_close); 

    drawerLayout.setDrawerListener(actionBarDrawerToggle); 
    actionBarDrawerToggle.syncState(); 

    drawerListView = (ListView) findViewById(R.id.drawer_listView); 

    // SELECT * FROM Sections where Fk == 0; 
    sectionsList = new RushSearch().whereEqual("Fk", 0).find(Sections.class); 
    Log.d("ELEMENTI",""+sectionsList.size()); 
    drawerListViewAdapter = new DrawerListViewAdapter(sectionsList, getApplicationContext()); 

    // Adapter che si occupa di popolare il drawer 
    drawerListView.setAdapter(drawerListViewAdapter); 


    // Listner per il click su un elemento del drawer 
    drawerListView.setOnItemClickListener(click); 
} 

La méthode callWebservice() est responsabile de prendre un fichier JSON à partir d'une URL et son code est cette

private void callWebservice() { 

    String tag_json_obj = "GetItem"; 
    String url = String.format("http://digitalbox.getsandbox.com/item"); 
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() { 
     @Override 
     public void onResponse(JSONObject response) { 

      try { 
       saveSections(response.getJSONArray("Sections")); 

      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

     } 
    }, new Response.ErrorListener() { 
     public void onErrorResponse(VolleyError error) { 
      VolleyLog.d("Settings", "Error: " + error.getMessage()); 
     } 
    }) { 
     @Override 
     public Map<String, String> getHeaders() throws AuthFailureError { 
      HashMap<String, String> headers = new HashMap<String, String>(); 
      headers.put("Content-Type", "application/json"); 
      headers.put("Accept", "application/json"); 
      return headers; 
     } 
    }; 
    NetworkController.getInstance().addToRequestQueue(jsonObjectRequest, tag_json_obj); 
} 

private void saveSections(final JSONArray section) { 

    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 


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

       try { 
        JSONObject obj = section.getJSONObject(i); 

        Sections s = new RushSearch().whereEqual("ID", obj.getInt("ID")).findSingle(Sections.class); 
        if (s == null) { 
         s = new Sections(); 
         s.setID(obj.getInt("ID")); 
        } 

        if (!obj.isNull("Fk")) 
         s.setFk(obj.getInt("Fk")); 

        s.setTitle(obj.getString("Title")); 

        if (!obj.isNull("CategoryColor")) 
         s.setCategoryColor(obj.getString("CategoryColor")); 

        s.setPos(obj.getInt("Pos")); 
        s.setLanguageId(obj.getInt("LanguageId")); 
        s.setUnavailableForSend(obj.getBoolean("UnavailableForSend")); 

        s.save(); 

       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 

      Log.d("sections", "DB updated"); 


     } 
    }); 
    t.setPriority(Thread.MIN_PRIORITY); 
    t.start(); 
} 

Si je cours l'application avec Android Studio, dans un smartphone AVD, j'ai ce journal

11-30 15:21:53.520 2170-2170/? I/art: Not late-enabling -Xcheck:jni (already on) 
11-30 15:21:53.520 2170-2170/? I/art: Late-enabling JIT 
11-30 15:21:53.558 2170-2170/? I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000 
11-30 15:21:53.685 2170-2170/rawpepper.it.digitalbox W/System: ClassLoader referenced unknown path: /data/app/rawpepper.it.digitalbox-2/lib/x86 
11-30 15:21:54.099 2170-2170/rawpepper.it.digitalbox W/art: Before Android 4.1, method int android.support.v7.internal.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView 
11-30 15:21:54.469 2170-2170/rawpepper.it.digitalbox D/ELEMENT: 13 
11-30 15:21:54.486 2170-2210/rawpepper.it.digitalbox D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 
11-30 15:21:54.592 2170-2210/rawpepper.it.digitalbox I/OpenGLRenderer: Initialized EGL, version 1.4 
11-30 15:21:54.719 2170-2210/rawpepper.it.digitalbox W/EGL_emulation: eglSurfaceAttrib not implemented 
11-30 15:21:54.719 2170-2210/rawpepper.it.digitalbox W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xad6fc2e0, error=EGL_SUCCESS 
11-30 15:21:57.542 2170-2204/rawpepper.it.digitalbox D/Volley: [117] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://digitalbox.getsandbox.com/item 0x95b78f5f NORMAL 1> [lifetime=3034], [size=196862], [rc=200], [retryCount=0] 
11-30 15:21:57.691 2170-2180/rawpepper.it.digitalbox W/art: Suspending all threads took: 25.964ms 
11-30 15:21:57.909 2170-2405/rawpepper.it.digitalbox D/sections: DB updated 

qui me dit que le nombre d'éléments dans le tableau sectionList est 13 (sixième rangée), c'est correct. app run with Android Studio Si je crée l'apk et je l'installe sur mon smartphone, et je branche ce sur PC pour vérifier le journal quand je lance l'application, j'ai ce journal

11-30 15:35:01.765 17183-17183/rawpepper.it.digitalbox I/art: Late-enabling -Xcheck:jni 
11-30 15:35:01.883 17183-17183/rawpepper.it.digitalbox W/System: ClassLoader referenced unknown path: /data/app/rawpepper.it.digitalbox-2/lib/arm 
11-30 15:35:02.357 17183-17183/rawpepper.it.digitalbox W/art: Before Android 4.1, method int android.support.v7.internal.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView 
11-30 15:35:03.235 17183-17183/rawpepper.it.digitalbox D/ELEMENT: 0 
11-30 15:35:03.249 17183-17260/rawpepper.it.digitalbox D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 
11-30 15:35:03.304 17183-17260/rawpepper.it.digitalbox I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 09/02/15, 76f806e, Ibddc658e36 
11-30 15:35:03.306 17183-17260/rawpepper.it.digitalbox I/OpenGLRenderer: Initialized EGL, version 1.4 
11-30 15:35:05.976 17183-17321/rawpepper.it.digitalbox D/sections: DB updated 

qui me dit que les éléments sectionList array est 0, mais si je le ferme et l'exécute à nouveau, tout est correct.

+0

Sans lire après la 3ème ligne de code, je devine que 'callWebservice();' est utilisé pour remplir le tiroir. Donc, vous devez attendre la réponse et le charger puis – codeMagic

+0

le tiroir est rempli dans la méthode onCreate avec cette ligne de code 'sectionsList = new RushSearch(). WhereEqual (" Fk ", 0) .find (Sections.class); Log.d ("ELEMENTI", "" + sectionsList.size()); drawerListViewAdapter = new DrawerListViewAdapter (sectionsList, getApplicationContext()); ' – Dennis

+0

oui mais vous n'êtes pas sûr que les informations que vous recherchez sont stockées. L'appel au service Web est asynchrone, il est donc possible que vous essayez de lire les données qui ne sont pas déjà reçues du service Web – baki

Répondre

0

Ok Man. Essayez ceci:

private void callWebservice() { 
    String tag_json_obj = "GetItem"; 
    String url = String.format("http://digitalbox.getsandbox.com/item"); 
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() { 
     @Override 
     public void onResponse(JSONObject response) { 

      try { 
       new SaveData().execute(response.getJSONArray("Sections")); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

     } 
    }, new Response.ErrorListener() { 
     public void onErrorResponse(VolleyError error) { 
      VolleyLog.d("Settings", "Error: " + error.getMessage()); 
     } 
    }) { 
     @Override 
     public Map<String, String> getHeaders() throws AuthFailureError { 
      HashMap<String, String> headers = new HashMap<String, String>(); 
      headers.put("Content-Type", "application/json"); 
      headers.put("Accept", "application/json"); 
      return headers; 
     } 
    }; 
    NetworkController.getInstance().addToRequestQueue(jsonObjectRequest, tag_json_obj); 
} 

Puis ajouter cette classe interne à l'intérieur de votre activité:

private final class SaveData extends AsyncTask<JSONArray, Void, Void> { 
    protected Void doInBackground(JSONArray... params) { 
     int c = section.length(); 
     for (int i = 0; i < c; i++) { 

      try { 
       JSONObject obj = section.getJSONObject(i); 

       Sections s = new RushSearch().whereEqual("ID", obj.getInt("ID")).findSingle(Sections.class); 
       if (s == null) { 
        s = new Sections(); 
        s.setID(obj.getInt("ID")); 
       } 

       if (!obj.isNull("Fk")) 
        s.setFk(obj.getInt("Fk")); 

       s.setTitle(obj.getString("Title")); 

       if (!obj.isNull("CategoryColor")) 
        s.setCategoryColor(obj.getString("CategoryColor")); 

       s.setPos(obj.getInt("Pos")); 
       s.setLanguageId(obj.getInt("LanguageId")); 
       s.setUnavailableForSend(obj.getBoolean("UnavailableForSend")); 

       s.save(); 

      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 

     Log.d("sections", "DB updated"); 
     return null; 
    } 

    public void onPostExecute(Void result) { 
     sectionsList = new RushSearch().whereEqual("Fk", 0).find(Sections.class); 
     Log.d("ELEMENTI",""+sectionsList.size()); 
     drawerListViewAdapter = new DrawerListViewAdapter(sectionsList, getApplicationContext()); 
    } 
} 

J'espère que cela aide!

+0

J'ai une erreur dans 'int c = params.length();' (Appel de méthode attendu) et dans 'JSONObject obj = section.getJSONObject (i);' (impossible de résoudre la méthode getJSONObject (int)) – Dennis

+0

Man, vous devez remplacer la section par params [0] – Suncatcher

+0

Je suis votre cauchemar, mais j'ai le même problème .. :( – Dennis

0

Vous devez configurer le tiroir après le téléchargement des données. Par exemple en appelant saveDate() lors du téléchargement d'une nouvelle section et setUpDraw() dans onCreate().

private void saveData(Sections newSections) { 
    newSections.save() 
    setUpDraw() 
} 

private void setUpDraw() { 

    drawerListView = (ListView) findViewById(R.id.drawer_listView); 
    sectionsList = new RushSearch().whereEqual("Fk", 0).find(Sections.class); 
    drawerListViewAdapter = new DrawerListViewAdapter(sectionsList, context); // You don't want application context 
    drawerListView.setAdapter(drawerListViewAdapter); 
    drawerListView.setOnItemClickListener(click); 
} 
+0

uhm ... Je ne comprends pas l'utilité de la méthode 'saveData()'. J'ai la méthode 'saveSections()' ... – Dennis

+0

Le point était juste d'appeler setUpDraw() après l'enregistrement. Je ne voulais simplement pas copier tout votre code. Aussi mon implémentation de setUpDraw() est peu susceptible d'être complète, je vous laisse le soin de remplir les espaces vides. –

0

Je pense que vous devriez appeler cette partie de votre code:

// SELECT * FROM Sections where Fk == 0; 
sectionsList = new RushSearch().whereEqual("Fk", 0).find(Sections.class); 
Log.d("ELEMENTI",""+sectionsList.size()); 
drawerListViewAdapter = new DrawerListViewAdapter(sectionsList, getApplicationContext()); 

// Adapter che si occupa di popolare il drawer 
drawerListView.setAdapter(drawerListViewAdapter); 

Après la méthode saveSections() se termine. Quelque chose comme ceci:

private void callWebservice() { 

String tag_json_obj = "GetItem"; 
String url = String.format("http://digitalbox.getsandbox.com/item"); 
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() { 
    @Override 
    public void onResponse(JSONObject response) { 
     try { 
      saveSections(response.getJSONArray("Sections")); 
// SELECT * FROM Sections where Fk == 0; 
sectionsList = new RushSearch().whereEqual("Fk", 0).find(Sections.class); 
Log.d("ELEMENTI",""+sectionsList.size()); 
drawerListViewAdapter = new DrawerListViewAdapter(sectionsList, getApplicationContext()); 

// Adapter che si occupa di popolare il drawer 
drawerListView.setAdapter(drawerListViewAdapter); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

    } 
}, new Response.ErrorListener() { 
    public void onErrorResponse(VolleyError error) { 
     VolleyLog.d("Settings", "Error: " + error.getMessage()); 
    } 
}) { 
    @Override 
    public Map<String, String> getHeaders() throws AuthFailureError { 
     HashMap<String, String> headers = new HashMap<String, String>(); 
     headers.put("Content-Type", "application/json"); 
     headers.put("Accept", "application/json"); 
     return headers; 
    } 
}; 
NetworkController.getInstance().addToRequestQueue(jsonObjectRequest, tag_json_obj); 

}

+0

J'ai essayé avec vos solutions mais j'ai le même problème. La listView dans Drawer ne se remplit pas lors de la première exécution. – Dennis

+0

Après la méthode saveSections(), votre sectionList est remplie? Qu'est-ce que votre logcat imprime? – Suncatcher

+0

Si je place 'Log.d (numberOfElement_tag," "+ sectionsList.size())' après l'appel à la méthode 'saveSections()' (après la ligne 'saveSections (response.getJSONArray (" Sections ")); 'dans' callWebservice() '), logcat me dit' 12-01 15: 52: 00.237 23332-23332/rawpepper.it.digitalbox D/Nombre d'élément dans sectionList: 0' (Si j'installe apk sur mon smartphone, si Je cours l'application dans AVD dans Android Studio tout est ok et le nombre d'éléments dans sectionList est 13) – Dennis

0

J'ai modifié mon code, maintenant j'ai ce code pour la méthode onCreate()

protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     callWebservice(); 

//  setContentView(R.layout.activity_main); 

     // Layout principale col drawer 
     setContentView(R.layout.activity_main_drawer); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
     leftArrow = (ImageView) findViewById(R.id.left_arrow); 
     titolo = (TextView) findViewById(R.id.titolo_id); 

     ActionBarDrawerToggle actionBarDrawerToggle = 
       new ActionBarDrawerToggle(this, drawerLayout, toolbar, 
         R.string.navigation_drawer_open, R.string.navigation_drawer_close); 

     drawerLayout.setDrawerListener(actionBarDrawerToggle); 
     actionBarDrawerToggle.syncState(); 

     drawerListView = (ListView) findViewById(R.id.drawer_listView); 
     setupDrawer(); 

    } 

où la méthode setupDrawer() est

private void setupDrawer() { 
     // SELECT * FROM Sections where Fk == 0; 
     sectionsList = new RushSearch().whereEqual("Fk", 0).find(Sections.class); 
     Log.d("ELEMENT", "" + sectionsList.size()); 
     drawerListViewAdapter = new DrawerListViewAdapter(sectionsList, getApplicationContext()); 

     // Adapter che si occupa di popolare il drawer 
     drawerListView.setAdapter(drawerListViewAdapter); 

     // Listner per il click su un elemento del drawer 
     drawerListView.setOnItemClickListener(click); 
    } 

Si j'appelle cette méthode de onCreate() ou de callWebservice() après saveSections(response.getJSONArray("Sections")); dans try-catch, j'ai le même problème.