Realm对象只能在创建它们的线程上访问

时间:2017-07-04 12:20:13

标签: java android json multithreading realm

我正在从网址下载JSON数据,因为我计划在多个活动中使用它,我使用Realm离线存储它,现在当我尝试从mainactivity访问存储的数据时,它工作正常,但数据是这样的,它是一个由两个以上的arraylists(嵌套的arraylists)组成的arraylist。 因此,每当我想要访问第二个屏幕中主对象的一个​​arraylists时,我就会将对象的位置从main发送到second。我正试图从那里获取数据。但它显示出错误。

任何帮助将不胜感激。提前谢谢。

堆栈跟踪

    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(问题活动)

    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 Class

    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);
        }
    }

1 个答案:

答案 0 :(得分:0)

您可以在AsyncTask中抽象数据请求的所有逻辑,并决定是否返回领域数据或服务数据。