【问题标题】:Retrofit2 and DBFlow to Read Save and Entity DetailsRetrofit2 和 DBFlow 读取保存和实体详细信息
【发布时间】:2019-05-18 13:02:00
【问题描述】:

我正在使用 retrofit2 对某些资源进行网络请求。预期的相应响应是这样的:

{
            "coach_details":[
            {
                "coach_id": 8,
                "academy_id": 1,
                "username": "coach2@gmail.com",
                "first_name": "David",
                "last_name": "test",
                "gender": "male",
                "email": "",
                "mobile": "", 
                "middle_name": "",
                "nick_name": "", 
                "state": "3"
            }
            ],
            "status": 1,
            "message": "success"
        }

        or

        {
            "status": 0,
            "message": "Oops! Invalid username or password!"
        }

这是我的应用程序的登录端点,随后我添加了 DBFLow 作为 ORM 数据库。我对 DBFlow 和 retrofit2 使用相同的模型类,如下所示:

主要响应的教练班:

public class Coach {

private String status;
private String message;

@SerializedName("coach_details")
private CoachDetails coachDetails;

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public CoachDetails getCoachDetails() {
    return coachDetails;
}

public void setCoachDetails(CoachDetails coachDetails) {
    this.coachDetails = coachDetails;
}
}

以及要保存的对象的教练详细信息

@Table(database = SportsDatabase.class)
public class CoachDetails extends BaseModel {

@SerializedName("coach_id")
@PrimaryKey
@Column
public String coachId;

@SerializedName("academy_id")
public String academyId;

@SerializedName("username")
public String username;

@SerializedName("first_name")
public String firstName;

@SerializedName("last_name")
public String lastName;

@SerializedName("gender")
public String gender;

@SerializedName("mobile")
public String mobileNum;

@SerializedName("email")
public String emailAddr;

@SerializedName("middle_name")
public String midName;

@SerializedName("nick_name")
public String nickName;

@SerializedName("state")
public String originState;

public CoachDetails() {
}

public String getCoachId() {
    return coachId;
}

public void setCoachId(String coachId) {
    this.coachId = coachId;
}

public String getAcademyId() {
    return academyId;
}

public void setAcademyId(String academyId) {
    this.academyId = academyId;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getGender() {
    return gender;
}

public void setGender(String gender) {
    this.gender = gender;
}

public String getMobileNum() {
    return mobileNum;
}

public void setMobileNum(String mobileNum) {
    this.mobileNum = mobileNum;
}

public String getEmailAddr() {
    return emailAddr;
}

public void setEmailAddr(String emailAddr) {
    this.emailAddr = emailAddr;
}

public String getMidName() {
    return midName;
}

public void setMidName(String midName) {
    this.midName = midName;
}

public String getNickName() {
    return nickName;
}

public void setNickName(String nickName) {
    this.nickName = nickName;
}

public String getOriginState() {
    return originState;
}

public void setOriginState(String originState) {
    this.originState = originState;
}

public void insertInfo(String coach_id, String acadId, String username, String first, String last, String gender, String mobile, String mid_name, String nick, String state) {
    this.coachId = coach_id;
    this.academyId = acadId;
    this.username = username;
    this.firstName = first;
    this.lastName = last;
    this.gender = gender;
    this.mobileNum = mobile;
    this.midName = mid_name;
    this.nickName = nick;
    this.originState = state;
}
}

在我的活动中,我尝试在网络调用后保存,如下面的代码,还尝试测试从数据库中读取但在日志中获取空值。我的保存是否正确或我的读取查询错误? 示例代码:

private void attemptLogin(String username, String pwd) {
    Call<Coach> call = RestClient.getRestInstance()
            .getLoginService()
            .loginCoach("testcoach@gmail.com", "123@abcd"); // TODO: 12/17/2018 Use input values

    call.enqueue(new Callback<Coach>() {
        @Override
        public void onResponse(Call<Coach> call, Response<Coach> response) {
            if (response.isSuccessful()) {

                Coach coach = response.body();

                coach_id = coach.getCoachDetails().getCoachId();

                String acadId = coach.getCoachDetails().getAcademyId();
                String username = coach.getCoachDetails().getUsername();
                String first = coach.getCoachDetails().getFirstName();
                String last = coach.getCoachDetails().getLastName();
                String gender = coach.getCoachDetails().getGender();
                String mobile = coach.getCoachDetails().getMobileNum();
                String email = coach.getCoachDetails().getEmailAddr();
                String mid_name = coach.getCoachDetails().getMidName();
                String nick = coach.getCoachDetails().getNickName();
                String state = coach.getCoachDetails().getOriginState();
 //                    Log.d(TAG, "State:\t" + state);

                CoachDetails coachDetails = new CoachDetails();
//                    coachDetails.insertInfo(coach_id, acadId, username, first, last, gender, mobile, mid_name, nick, state);
                coachDetails.setCoachId(coach_id);
                coachDetails.setAcademyId(acadId);
                coachDetails.setFirstName(first);
                coachDetails.setLastName(last);
                coachDetails.setGender(gender);
                coachDetails.setMobileNum(mobile);
                coachDetails.setEmailAddr(email);
                coachDetails.setMidName(mid_name);
                coachDetails.setNickName(nick);
                coachDetails.setOriginState(state);
                coachDetails.save();

 //                    CoachDetails details = SQLite.select()
 //                            .from(CoachDetails.class)
//                            .querySingle();

 //                    Log.d(TAG, "CId from db:\t" + details.getCoachId() + " first_name:\t" + details.getFirstName()); // name is null and id is showing properly

 //                    startActivity(new Intent(LoginActivity.this, MainActivity.class));
            } else {
                Snackbar.make(findViewById(android.R.id.content), "Login Failed with Error Code:\t" + response.code(),
                        Snackbar.LENGTH_LONG).show();
                loginBtn.setEnabled(true);
            }
        }

        @Override
        public void onFailure(Call<Coach> call, Throwable t) {
            Snackbar.make(findViewById(android.R.id.content), "Unable to Login...Check Your Connection or Credentials",
                    Snackbar.LENGTH_LONG).show();
        }
    });
}

谁能指出哪里出错了?

【问题讨论】:

  • 首先你的教练是数组而不是响应实体。
  • 我仍然能够从响应中获取字段,我已经测试过问题在于保存或读取数据
  • 这怎么可能,确保您在上面的示例中发布了正确的 json 格式..?
  • 你能显示Coach类吗??
  • 仍然令人困惑..为什么在Coach 类中你的coach_details 是对象而不是数组。而在 json 中它的数组 ...!!!

标签: android retrofit2 dbflow


【解决方案1】:

我已通过在模型类的其余字段中添加@Column 注释来解决此问题。问题是我从ActiveAndroid to DBFlow 移出并忘记在调用它们之前正确注释我的字段。

我现在得到了想要的输出。

【讨论】:

    【解决方案2】:

    我的保存是否正确或我的读取查询有误?

    尝试以下解决方案...

     private void attemptLogin(String username, String pwd) {
        Call<Coach> call = RestClient.getRestInstance()
                .getLoginService()
                .loginCoach("testcoach@gmail.com", "123@abcd"); // TODO: 12/17/2018 Use input values
    
        call.enqueue(new Callback<Coach>() {
            @Override
            public void onResponse(Call<Coach> call, Response<Coach> response) {
                if (response.isSuccessful()) {
    
    
                    updateData(response.body())
    
    
                } else {
                    Snackbar.make(findViewById(android.R.id.content), "Login Failed with Error Code:\t" + response.code(),
                            Snackbar.LENGTH_LONG).show();
                    loginBtn.setEnabled(true);
                }
            }
    
            @Override
            public void onFailure(Call<Coach> call, Throwable t) {
                Snackbar.make(findViewById(android.R.id.content), "Unable to Login...Check Your Connection or Credentials",
                        Snackbar.LENGTH_LONG).show();
            }
        });
    }
    
    
    
    private void updateData(Coach coach){
    
         coach_id = coach.getCoachDetails().getCoachId();
    
         new MyAsyncTask (this,coach.getCoachDetails()).execute();
    
    
         //add here AsynTask and save this `coachDetails` object inside the `doBackground()` method.
    
    }
    

    注意:- 尝试在某个后台线程上完成所有数据库工作,否则您将在某些设备上收到 ANR 错误。因为你在 UI Thread 上做所有的操作。

    例子:-

     class MyAsyncTask extends AsyncTask<String, Void, String> {
    
            private Context context;
            private CoachDetails coachDetails;
    
            public MyAsyncTask(Context context,CoachDetails coachDetails) {
            this.coachDetails=coachDetails;
            this.context=context;
            }
    
            @Override
            protected String doInBackground(String... params) {
                coachDetails.save();
             return null;
            }
    
            @Override
            protected void onPostExecute(String s) {
    
    
         //                    CoachDetails details = SQLite.select()
     //                            .from(CoachDetails.class)
    //                            .querySingle();
    
     //                    Log.d(TAG, "CId from db:\t" + details.getCoachId() + " first_name:\t" + details.getFirstName()); // name is null and id is showing properly
    
     //                    startActivity(new Intent(LoginActivity.this, MainActivity.class));
    
            }
        }
    

    注意:插入将需要时间将行插入数据库。您无需等待即可访问它。

    完成这些操作后,您的数据未显示,则您的数据库为空。 关注Tutorial 并了解 DBFlow。

    【讨论】:

    • 我用响应设置的字段调用了 coachDetails.save()。你在哪里做的?
    • 检查 onResponse of Call
    • 谢谢我已经修好了。检查我的答案,这是我的疏忽
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 2014-11-08
    • 2019-04-23
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多