2017-07-04 4 views
1

Ich lade JSON-Daten von einer URL und da ich es über viele Aktivitäten zu verwenden plane, speicher ich es offline mit Realm, jetzt, wenn ich versuche, auf die gespeicherte zuzugreifen Daten von Hauptaktivität, es funktioniert gut, aber die Daten sind so, dass es eine Arraylist bestehend aus zwei weiteren Arraylisten (verschachtelten Arraylisten) ist. Also, wenn ich auf eine der Arraylists des Hauptobjekts im zweiten Bildschirm zugreifen möchte, sende ich die Position des Objekts von Haupt zu Sekunde. und versuche, die Daten von dort zu bekommen. aber es zeigt diesen Fehler.Realm-Objekte können nur auf den Thread zugegriffen werden, die sie erstellt wurden

Jede Hilfe wäre willkommen. Danke im Voraus.

Stack Trace

FATAL EXCEPTION: main 
                     Process: com.example.vamshi.baking, PID: 2643 
                     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.vamshi.baking/com.example.vamshi.baking.UI.SecondScreenDetails}: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created. 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2449) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2509) 
                      at android.app.ActivityThread.access$1000(ActivityThread.java:153) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:5527) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) 
                      Caused by: java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created. 
                      at io.realm.BaseRealm.checkIfValid(BaseRealm.java:385) 
                      at io.realm.IngredientsRealmProxy.realmGet$quantity(IngredientsRealmProxy.java:98) 
                      at com.example.vamshi.baking.Data.Ingredients.getQuantity(Ingredients.java:28) 
                      at com.example.vamshi.baking.UI.SecondScreenDetails.setDisplay(SecondScreenDetails.java:63) 
                      at com.example.vamshi.baking.UI.SecondScreenDetails.onCreate(SecondScreenDetails.java:42) 
                      at android.app.Activity.performCreate(Activity.java:6303) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2402) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2509)  
                      at android.app.ActivityThread.access$1000(ActivityThread.java:153)  
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)  
                      at android.os.Handler.dispatchMessage(Handler.java:102)  
                      at android.os.Looper.loop(Looper.java:154)  
                      at android.app.ActivityThread.main(ActivityThread.java:5527)  
                      at java.lang.reflect.Method.invoke(Native Method)  
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)  
07-04 17:42:44.452 2643-2643/com.example.vamshi.baking E/MQSEventManagerDelegate: failed to get MQSService. 

MainActivity

public class MainActivity extends AppCompatActivity { 


    public static ListView myList; 
    public static ListAdapter myAdapter; 
    public static Realm realm; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Realm.init(this); 
     realm = Realm.getDefaultInstance(); 

     DownloadTask newTask = new DownloadTask(); 
     newTask.execute("hi"); 
     setContentView(R.layout.activity_main); 
     myList = (ListView) findViewById(R.id.Recipe_list); 

     // getData(); 

     setDisplay(); 

     myList.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       String p = String.valueOf(position); 
//    Toast.makeText(MainActivity.this, p, Toast.LENGTH_SHORT).show(); 
       Intent in = new Intent(MainActivity.this, SecondScreenDetails.class); 
       in.putExtra("Position", p); 
       startActivity(in); 
      } 
     }); 

    } 

    public void setDisplay(){ 

     ArrayList<Recipe> finalRecipies = new ArrayList<>(); 
     RealmResults<Recipe> rrRecipies = realm.where(Recipe.class).findAll(); 

     for(Recipe r: rrRecipies){ 
      finalRecipies.add(r); 
//   Toast.makeText(this, r.getName(), Toast.LENGTH_SHORT).show(); 
     } 
     myAdapter = new ListViewAdapter(this, finalRecipies); 
     myList.setAdapter(myAdapter); 

    } 


    @Override 
    protected void onDestroy() { 
     realm.close(); 
     super.onDestroy(); 
    } 
} 

SecondScreenActivity (Problem Aktivität)

public class SecondScreenDetails extends AppCompatActivity { 

    public Realm realm; 
    @BindView(R.id.ingredients_list)RecyclerView ingre_list; 
    @BindView(R.id.steps_button)Button next_button; 
    public int position; 
    public static SecondScreenRecyclerViewAdapter myAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_second_screen_details); 
     Realm.init(this); 
     realm = Realm.getDefaultInstance(); 
     setDisplay(); 
     ButterKnife.bind(this); 
     next_button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

      } 
     }); 
    } 

    private void setDisplay() { 
     ArrayList<Recipe> finalRecipies = new ArrayList<>(); 
     ArrayList<Ingredients> finalIngredients = new ArrayList<>(); 
     RealmResults<Recipe> rrRecipies = realm.where(Recipe.class).findAll(); 
     Intent in = getIntent(); 
     position = Integer.parseInt(in.getStringExtra("Position")); 
     for(Recipe r: rrRecipies){ 
      finalRecipies.add(r); 
     } 
     int i = finalRecipies.get(position).getIngredients().size(); 
     for(int j = 0 ; j<i ; j++){ 
      Ingredients n = new Ingredients(finalRecipies.get(position).getIngredients().get(j).getQuantity(), 
        finalRecipies.get(position).getIngredients().get(j).getMeasure(), 
        finalRecipies.get(position).getIngredients().get(j).getIngredient()); 
      finalIngredients.add(n); 
     } 
     myAdapter = new SecondScreenRecyclerViewAdapter(finalIngredients); 
     RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext()); 
     ingre_list.setLayoutManager(mLayoutManager); 
     ingre_list.setItemAnimator(new DefaultItemAnimator()); 
     ingre_list.setAdapter(myAdapter); 
    } 
} 

DownloadingData Klasse

public class DownloadTask extends AsyncTask<String,Void,String> { 


    private RealmList<Recipe> realmRecipe = new RealmList<>(); 
    String result; 

    @Override 
    protected String doInBackground(String... params) { 
     result = ""; 
     Realm realm = null; 
      realm = Realm.getDefaultInstance(); 
      realm.executeTransaction(new Realm.Transaction() { 
       @Override 
       public void execute(Realm realm) { 
        OkHttpClient client = new OkHttpClient(); 
        Request request = new Request.Builder().url("https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/baking.json").build(); 
        try { 
         result = client.newCall(request).execute().body().string(); 
         Log.i("RESULT", result); 
         JSONArray rootArray = new JSONArray(result); 
         for (int i = 0; i < rootArray.length(); i++) { 
          JSONObject tempObject = rootArray.getJSONObject(i); 
          JSONArray jIngredients = tempObject.getJSONArray("ingredients"); 
          JSONArray jSteps = tempObject.getJSONArray("steps"); 

          // Get the ingredients 
          List<Ingredients> ingredients = new ArrayList<>(); 
          for (int j = 0; j < jIngredients.length(); j++) { 
           JSONObject tempIngredient = jIngredients.getJSONObject(j); 
           Ingredients nIngredient = realm.createObject(Ingredients.class); 
           nIngredient.setIngredient(tempIngredient.getString("ingredient")); 
           nIngredient.setMeasure(tempIngredient.getString("measure")); 
           nIngredient.setQuantity(tempIngredient.getString("quantity")); 
//        Ingredients newIngredient = new Ingredients(tempIngredient.getString("quantity"), 
//          tempIngredient.getString("measure"), 
//          tempIngredient.getString("ingredient")); 
//        ingredients.add(newIngredient); 
           ingredients.add(nIngredient); 
          } 

          // Get the steps 
          List<Steps> steps = new ArrayList<>(); 
          for (int j = 0; j < jSteps.length(); j++) { 
           JSONObject tempStep = jSteps.getJSONObject(j); 
           Steps nStep = realm.createObject(Steps.class); 
           nStep.setDescription(tempStep.getString("description")); 
           nStep.setId(tempStep.getString("id")); 
           nStep.setShortDescription(tempStep.getString("shortDescription")); 
           nStep.setVideoURL(tempStep.getString("videoURL")); 
           steps.add(nStep); 
//        Steps newStep = new Steps(tempStep.getString("id"), tempStep.getString("shortDescription"), 
//          tempStep.getString("description"), tempStep.getString("videoURL")); 
//        steps.add(newStep); 
          } 

          // Create the recipe 

          Recipe nRecipe = realm.createObject(Recipe.class); 
          nRecipe.setId(tempObject.getString("id")); 
          nRecipe.setName(tempObject.getString("name")); 
          nRecipe.setServings(tempObject.getString("servings")); 
          nRecipe.setIngredients(ingredients); 
          nRecipe.setSteps(steps); 
          realmRecipe.add(nRecipe); 
//       Recipe newRecipe = new Recipe(tempObject.getString("id"), tempObject.getString("name"), tempObject.getString("servings"), ingredients, steps); 
//       MainActivity.mRecipies.add(newRecipe); 

         } 
        }catch (Exception e){ 
         Log.i("Error Message", e.getMessage()); 
        } 

       } 
      }); 


     return null; 
    } 

    @Override 
    protected void onPostExecute(String s) { 

      super.onPostExecute(s); 
     } 
    } 
+0

Welche Version von Realm ist das? – EpicPandaForce

+0

seine neueste (3.4.0) –

+0

Mit 'private RealmList realmRecipe = neue RealmList <>();' als ein Feld in Ihnen AsyncTask, sieht aus wie eine einfache Möglichkeit, versehentlich auf Daten aus dem falschen Thread zuzugreifen. Ich würde damit beginnen, das zu entfernen. –

Antwort

0

Sie können die gesamte Logik der Datenanforderung in der AsyncTask abstrahieren und entscheiden, ob Realmdaten oder Servicedaten zurückgegeben werden sollen.

+0

es tut mir leid, ich habe dich bekommen –

Verwandte Themen