android - 如何将 JSON 数据存储到 Realm 中并将其显示到 recyclerview 中

标签 android json gson realm retrofit

在我的应用中,我实现了一个回收 View 。我有一个 json 格式的 api,其中包含一个研究所的用户信息。现在最初我想将数据存储到 Realm DB 中,然后它们用这些数据填充我的 recyclerview。因此,我正在尝试获取此过程的一些工作文件。但我还没有找到任何明确的解释。我不确定它的正确程序。我是否需要使用 Httpurlconnection 获取所有数据,然后将其存储到 Realm。或者有什么替代方法可以做到这一点。

编辑问题

在得到一些建议后,我尝试了以下代码。我正在使用 Retrofit 1.9。因为我无法使用 Retrofit 2+ 版本获取数据。当我从改造 1.9 中得到结果时。我想以此为基础保留我的代码。但是现在对如何基于 Realm 设置适配器感到困惑。因为我有单独的模型类用于 json api 和 Realm 。我想首先将数据存储到 Realm ,然后将其填充到 recaclerview。此时,recyclerview 直接填充了服务器数据。

在得到答案的指导后,我按如下方式编辑了我的问题

Json 响应

    [
    {
    "_id": "fhfh49879787989",
    "dn": "CN=9879798789",
    "whenChanged": "20170704065349.0Z",
    "name": "Student",
    "mail": "student@mail.com",
    "updated_at": "2017-07-04T18:22:43.624Z"
  },
  {
    "_id": "595bdcf32c67a3f9ee6c2a25",
    "dn": "CN=dsfdsfsdfsf",
    "givenName": "Accounting Office",
    "whenChanged": "20170801114732.0Z",
    "name": "Accounting",
    "mail": "accounting@mail.com",
    "updated_at": "2017-07-04T18:22:43.641Z"
  },
  {
    "_id": "584ab3b4122d13e1b0d1578d",
    "dn": "CN=sfdfsfsdfl",
    "sn": "Abels",
    "title": "Student",
    "givenName": "Gardrut",
    "whenChanged": "20170807150844.0Z",
    "department": "PMO",
    "company": "Multi Lmited",
    "name": "Mike Lizz",
    "mail": "mail@yahoo.com",
    "mobile": "+1321646498",
    "updated_at": "2016-12-09T13:37:56.175Z"
  },
  {
    "_id": "584ab3b3122d13e1b0d15735",
    "dn": "CN=xdfsdfsfsdf",
    "sn": "Acsdff",
    "title": "Software Engineer",
    "givenName": "Olin",
    "whenChanged": "20170810064841.0Z",
    "department": "Head",
    "company": "Private limited",
    "name": "James Oliver",
    "mail": "mail@gmail.com",
    "mobile": "+41228",
    "updated_at": "2016-12-09T13:37:55.813Z"
  },
  ....
 ]

我的模型类

    public class ColleagueModel {

    @Expose
    private String _id;
    @Expose
    private String dn;
    @Expose
    private String givenName;
    @Expose
    private String whenChanged;
    @Expose
    private String name;
    @Expose
    private String mail;
    @Expose
    private String updatedAt;
    @Expose
    private String sn;
    @Expose
    private String title;
    @Expose
    private String department;
    @Expose
    private String company;
    @Expose
    private String mobile;

    public ColleagueModel(){

    }
    //getter and setter

   }

我使用的库

compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp:2.3.0'
compile 'com.google.code.gson:gson:2.3'
compile 'com.squareup.picasso:picasso:2.5.2'

API服务

public interface ColleagueApiService {

@GET("/api/users")

void getColleague(Callback<String> flowers);

RestManagerClass

    public class ColleagueRestManager {

    public ColleagueApiService mColleagueApi;


    public ColleagueApiService getColleagueApi() {

        if (mColleagueApi == null) {
            GsonBuilder gson = new GsonBuilder();
            gson.registerTypeAdapter( String.class, new StringDeserializer() );

            mColleagueApi = new RestAdapter.Builder()
                    .setEndpoint( Constants.HTTP.BASE_URL )
                    .setConverter( new GsonConverter( gson.create() ) )
                    .build()
                    .create( ColleagueApiService.class );
        }
        return mColleagueApi;
    }
}

适配器类

public class MyColleaguesAdapter extends RecyclerView.Adapter<MyColleaguesAdapter.ColleagueHolder>/{

public static String TAG = MyColleaguesAdapter.class.getSimpleName();

private List<ColleagueModel> mColleague;

private Context context;

public interface ColleagueListListener {
}

public MyColleaguesAdapter(List<ColleagueModel> colleagues,Context context) 
{
    this.context=context;
    mColleague = colleagues;
}
public void addColleague(ColleagueModel colleague) {
    //Log.d(TAG,colleague.name);
    mColleague.add(colleague);
    notifyDataSetChanged();
}



@Override
public ColleagueHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.colleage_row_layout,parent,false);
    return new ColleagueHolder(view);
}
@Override
public void onBindViewHolder(ColleagueHolder holder, int position) {

    final ColleagueModel currentColleague = mColleague.get(position);
    Picasso.with(holder.itemView.getContext());
    holder.colleagueName.setText(currentColleague.getName());
    holder.companyName.setText(currentColleague.getCompany());
    holder.jobTitle.setText(currentColleague.getTitle());

    holder.colleaguePicture.setImageResource( R.drawable.profile_image );
    Picasso.with(holder.itemView.getContext()).load( Constants.HTTP.PHOTO_URL + currentColleague.getMail()).into(holder.colleaguePicture);

    holder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent i=new Intent(context,DetailMyColleague.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.putExtra("IMAGE_URL",Constants.HTTP.PHOTO_URL + currentColleague.getMail());
            i.putExtra("name",currentColleague.getName());
            i.putExtra("title",currentColleague.getTitle());
            i.putExtra("company",currentColleague.getCompany());
            i.putExtra("mobile",currentColleague.getMobile());
            i.putExtra("mail",currentColleague.getMail());
            i.putExtra("department",currentColleague.getDepartment());
            context.startActivity(i);
        }
    });


}

@Override
public int getItemCount() {
    return mColleague.size();
}

public class ColleagueHolder extends RecyclerView.ViewHolder{

    public CardView cardView;
    public ImageView colleaguePicture;
    public TextView  colleagueName;
    public TextView  companyName;
    public TextView  jobTitle;

    public ColleagueHolder(View itemView) {
        super(itemView);
        colleaguePicture= itemView.findViewById(R.id.colleague_picture);
        colleagueName= itemView.findViewById(R.id.colleague_name);
        companyName= itemView.findViewById(R.id.company_name);
        jobTitle= itemView.findViewById(R.id.job_title);
        cardView= itemView.findViewById(R.id.cardview_user);

      }
    }
 }

Controller 类

    public class Controller {

    private static final String TAG = Controller.class.getSimpleName();
    private UserCallbackListener mListener;
    private ColleagueRestManager mApiManager;

    public Controller(UserCallbackListener listener) {
        mListener = listener;
        mApiManager = new ColleagueRestManager();
    }

    public void startFetching(){

        mApiManager.getColleagueApi().getColleague(new Callback<String>() {
            @Override
            public void success(String s, Response response) {
                Log.d(TAG, "JSON :: " + s);

                try {
                    JSONArray array = new JSONArray(s);

                    for(int i = 0; i < array.length(); i++) {
                        JSONObject object = array.getJSONObject(i);

                        ColleagueModel colleague = new ColleagueModel();
                        colleague.setName( object.optString( "name" ) );
                        colleague.setCompany(object.optString("company"));
                        colleague.setTitle(object.optString("title"));
                        colleague.setMail( object.optString("mail"));
                        colleague.setMobile(object.optString("mobile"));
                        colleague.setDepartment(object.optString("department"));

                        mListener.onFetchProgress(colleague);

                    }

                } catch (JSONException e) {
                    mListener.onFetchFailed();
                }


                mListener.onFetchComplete();
            }

            @Override
            public void failure(RetrofitError error) {
                Log.d(TAG, "Error :: " + error.getMessage());
                mListener.onFetchComplete();
            }
        });

    }
    public interface UserCallbackListener{
        void onFetchStart();
        void onFetchProgress(ColleagueModel user);
        void onFetchProgress(List<ColleagueModel> userList);
        void onFetchComplete();
        void onFetchFailed();
    }

}

主要 Activity

public class MyColleaguesPage extends AppCompatActivity implements Controller.UserCallbackListener/*MyColleaguesAdapter.ColleagueListListener*/ {

private RecyclerView recyclerView;
private MyColleaguesAdapter adapter;
private List<ColleagueModel> mColleagueList = new ArrayList<>();
private Controller mController;

private Realm colleagueRealm;

private LinearLayoutManager layoutManager;

private RealmResults<MyColleagueModel> colleagueResult;

private List<MyColleagueModel> filteredModelList;
private RealmChangeListener realmListener;
private static final String DIALOG_TAG = "EmployeeDialog";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mycolleagues_layout);

    configViews();

    mController = new Controller(MyColleaguesPage.this);
    mController.startFetching();

    colleagueRealm = Realm.getDefaultInstance();


}

private void configViews() {
    recyclerView = this.findViewById(R.id.colleagues_recycler);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(MyColleaguesPage.this));
    recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());

    adapter = new MyColleaguesAdapter(mColleagueList,getApplicationContext());
    recyclerView.setAdapter(adapter);
}

RealmApplication 类

public class Application extends Application {

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

    Realm.init(this);
    RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
            .deleteRealmIfMigrationNeeded()
            .build();
    Realm.setDefaultConfiguration(realmConfiguration);
  }

Realm 模型

public class RealmUserModel extends RealmObject{
public static final String ID = "id";

private String id;
private String dn;
private String givenName;
private String whenChanged;
private String name;
private String mail;
private String updatedAt;
private String sn;
private String title;
private String department;
private String company;
private String mobile;

//getter and setter
}

最佳答案

1.) 使用 jsonschema2pojo.org 为 json 生成 API 响应类

public class EmployeeResponse {
    @SerializedName("_id")
    @Expose
    private String id;
    @SerializedName("dn")
    @Expose
    private String dn;
    @SerializedName("sn")
    @Expose
    private String sn;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("givenName")
    @Expose
    private String givenName;
    @SerializedName("whenChanged")
    @Expose
    private String whenChanged;
    @SerializedName("department")
    @Expose
    private String department;
    @SerializedName("company")
    @Expose
    private String company;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("mail")
    @Expose
    private String mail;
    @SerializedName("mobile")
    @Expose
    private String mobile;
    @SerializedName("updated_at")
    @Expose
    private String updatedAt;
       ....
}

2.) 从 http://square.github.io/retrofit/ 将 Retrofit 添加到您的项目中所以你甚至不会开始考虑使用 HttpUrlConnection

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.google.code.gson:gson:2.8.1'

3.) 你定义Retrofit接口(interface)

public interface ApiService {
    @GET("api/users")
    Call<List<User>> getUsers();
}

4.) 通过 Retrofit 创建 ApiService 实现

public class CustomApplication extends Application {
    // add to manifest ofc
    Retrofit retrofit;

    ApiService service;

    @Override
    public void onCreate() {
        super.onCreate();
        retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("https://app.com/")
            .build();

        service = retrofit.create(ApiService.class);
    }

    // get, get...
}

5.) 创建你的 RealmObject

public class Employee extends RealmObject {
    private String id ;
    private String dn ;
    private String givenName ;
    private String whenChanged ;
    private String name ;
    private String mail ;
    private String updatedAt ; // maybe Date?
    private String sn ;
    private String title;
    private String department;
    private String company;
    private String mobile;

    //getter and setter method    
}

6.) 创建映射来自 api 响应类的数据的类

public class EmployeeMapper {
    Employee toEmployee(EmployeeResponse response) {
        // ...
       return employee;
    }
}

7.) 将 Employee 写入 Realm

try(Realm r = Realm.getDefaultInstance()) {
    r.executeTransaction((realm) -> {
        realm.insertOrUpdate(employees);
    });
}

8.) 根据文档 https://realm.io/docs/java/latest/#adapters 通过 RealmRecyclerViewAdapter 监听 Realm 的变化

public class EmployeeAdapter extends RealmRecyclerViewAdapter<...

关于android - 如何将 JSON 数据存储到 Realm 中并将其显示到 recyclerview 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45696080/

相关文章:

java - 支持谷歌地图 API(v1 和 v2)的最佳方式是什么?

java - 如何使用java从内存中写入/读取内存

json - 如何使用 Enum 类型的字段执行 Typesafe JSON?

android - Android将位置模型转换为JSON字符串

android - 使用 GSON(序列化/反序列化库)时,我是否需要为模型类实现可序列化

android - 在 Android 的 ImageView 中渲染两个图像?

android - 如何在 Android 中的另一个 View 上为文本设置动画?

java - Android 将 unix 时间戳设置为 DatePicker

javascript - Highcharts 仪表在通过 json 获取数据之前渲染

java - 将具有不同对象的 json 数组解析为它们的类