2016-02-15 50 views
1

我目前有一個帶有listView的片段,我想用Realm的記錄填充它。在我的應用程序的第一次運行中,沒有記錄,所以我創建了一個asynctask從JSON文件填充數據庫。Realm在Android上不支持事務

問題是,如果評論asynctask調用new MuscleTask().execute();,沒有記錄被發現,如果交易沒有被持續。所以,當我更新代碼時,每當我在手機上運行應用程序時,數據庫都會被刷新,或者我在這裏做錯了什麼?

我是不是應該在asynctask中做這個,或者我只需要創建一個RealmAsyncTransaction,然後用RealmChangeListener做些什麼?

我的代碼沒有拋出任何異常。

public static class LandingWorkoutDirectoryFragment extends BaseFragment { 

    private RealmResults<Muscle> muscles; 
    private MuscleAdapter muscleAdapter; 
    private ListView listView; 

    public LandingWorkoutDirectoryFragment() { 
    } 

    /** 
    * Returns a new instance of this fragment for the given section 
    * number. 
    */ 
    public static LandingWorkoutDirectoryFragment newInstance() { 
     LandingWorkoutDirectoryFragment fragment = new LandingWorkoutDirectoryFragment(); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     muscles = getRealm().allObjects(Muscle.class); 
     new MuscleTask().execute(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_landing_workout_directory, container, false); 
     listView = (ListView) rootView.findViewById(R.id.listview_display_exercises); 
     muscleAdapter = new MuscleAdapter(getActivity(), muscles, true); 
     listView.setAdapter(muscleAdapter); 

     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       Log.d("Di click", String.valueOf(position)); 
       Intent intent = new Intent(getActivity(), DisplayExerciseActivity.class); 
       intent.putExtra("muscleId", muscles.get(position).getId()); 
       intent.putExtra("muscleName", muscles.get(position).getName()); 
       startActivity(intent); 
      } 
     }); 

     return rootView; 
    } 


    private class MuscleTask extends AsyncTask<Void, Void, Void> { 

     @Override 
     protected Void doInBackground(Void... params) { 
      Realm realm = Realm.getDefaultInstance(); 

      InputStream is = null; 
      try { 
       is = getActivity().getAssets().open("muscles.json"); 
       realm.beginTransaction(); 
       realm.createOrUpdateAllFromJson(Muscle.class, is); 
       realm.commitTransaction(); 
      } catch (IOException e) { 
       realm.cancelTransaction(); 
      } 

      return null; 
     } 
    } 
} 

這裏是我的肌肉接頭

public class MuscleAdapter extends RealmBaseAdapter<Muscle> implements ListAdapter { 

    static class ViewHolder { 
     @Bind(R.id.firstLine) TextView name; 
     @Bind(R.id.secondLine) TextView description; 
     @Bind(R.id.icon) ImageView image; 

     public ViewHolder(View view) { 
      ButterKnife.bind(this, view); 
     } 
    } 

    public MuscleAdapter(Context context, RealmResults<Muscle> realmResults, boolean automaticUpdate) { 
     super(context, realmResults, automaticUpdate); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder viewHolder; 

     if (convertView == null) { 
      convertView = inflater.inflate(R.layout.listview_item_exercise, parent, false); 
      viewHolder = new ViewHolder(convertView); 
      convertView.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolder) convertView.getTag(); 
     } 

     Muscle item = realmResults.get(position); 
     viewHolder.name.setText(item.getName()); 
     viewHolder.description.setText(item.getDescription()); 
     Glide.with(parent.getContext()).load(item.getImage()).into(viewHolder.image); 

     return convertView; 
    } 
} 

編輯:這是我的基本適配器。

public class BaseFragment extends Fragment { 

    public final String log = this.getClass().getSimpleName(); 

    public Realm realm; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     realm = Realm.getDefaultInstance(); 
    } 

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

    public Realm getRealm() { 
     return realm; 
    } 
} 

編輯2:添加我的應用程序應用類

public class FititApplication extends Application { 


    @Override 
    public void onCreate() { 
     super.onCreate(); 

     // Configure Realm for the application 
     RealmConfiguration realmConfiguration = new  RealmConfiguration.Builder(this).build(); 
     Realm.deleteRealm(realmConfiguration); // Clean slate 
     Realm.setDefaultConfiguration(realmConfiguration); // Make this Realm the default 
    } 
} 
+1

你的'getRealm()'實現是什麼樣的?你在'onPostExecute'中缺少一個'RealmChangeListener'或者一個調用(這兩者的實現都只會在你的適配器上調用'notifiyDataSetChanged()'),但這不是你的問題 - 如果數據持續存在,你應該看到它。 –

+0

@AdamS,我發佈了包含「getRealm()」聲明的BaseAdapter的代碼。 –

+0

看起來很好。你在任何地方提供Realm配置嗎?或者,您的部署配置中是否啓用了「部署時刪除」選項? (從內存中刪除) –

回答

0

正如@AdamS指出,此行Realm.deleteRealm()FititApplication類至極延伸從Application是我的問題。評論這行代碼是解決我的問題所需的一切。該行代碼每次都會丟失我的數據庫。