方法“Login”始终在使用Android Retrofit2时返回false。

huangapple go评论61阅读模式
英文:

Method Login always return false using Android Retrofit2

问题

public class AppLogin {

    UniversalResponse uniresp = new UniversalResponse();
    private Boolean hasil = true ;

    public Boolean getHasil() {
        return hasil;
    }

    public void setHasil(Boolean hasil) {
        this.hasil = hasil;
    }
    
    public Boolean authorize(String user, String passwd){
        APIInterface apiInterface;
        LoginModel logindata = new LoginModel();
        logindata.setUsername(user);
        logindata.setPassword(passwd);

        apiInterface = APIClient.getClient().create(APIInterface.class);

        //Call<UniversalResponse> call = apiInterface.doLogin(logindata.getUsername(), logindata.getPassword());
        Call<UniversalResponse> call = apiInterface.doLogin(user, passwd);
        call.enqueue(new Callback<UniversalResponse>() {
            @Override
            public void onResponse(Call<UniversalResponse> call, Response<UniversalResponse> response)
            {
                UniversalResponse uniresp = response.body();
                Log.d("Login Module - Value dr Hasil sebelum Reponse Successfull", getHasil().toString());
                if(response.isSuccessful() ) {
                    Log.d("Nama Service", uniresp.getService());
                    Log.d("Isi Message", uniresp.getMessage());
                    Log.d("Login Module - Value dr Hasil di DALAM Reponse Successfull", getHasil().toString());
                    if ( uniresp.getMessage().equals("Success") && uniresp.getService().equals("MobileAppLogin") )
                    {
                        setHasil(true);
                        Log.d("Login Module - Value dr Hasil di DALAM Reponse Successfull dlm If Getmessasge Equals", getHasil().toString());
                    }
                    else {  
                        setHasil(false);
                        Log.d("Login Module - Value dr Hasil di DALAM Reponse Successfull dlm If Getmessasge Equals Equals ELSE Section", getHasil().toString());   
                    }

                }
                Log.d("Login Module - Value dr Hasil di LUAR Reponse Successfull", getHasil().toString());

            }

            @Override
            public void onFailure(Call<UniversalResponse> call, Throwable t) {
                call.cancel();
                hasil= false;
            }
        });

        Log.i("Login Module - Value dr Hasil di DEKAT RETURN PALING BAWAH", getHasil().toString());

        return getHasil();

    }

}
英文:

I've wrote Java code on Android Studio. I've made Login method and something happened within my code. It hadn't return proper return value. The Return Value always False. While I've checked with LogD function on Android Studio, the Boolean variable has been changed properly but It has changed again in the end of method so the Login method always return false & I can't proceed to login.

Please help me to resolve this confusing moment. Any answer will be appreciated, Thanks a bunch.

public class AppLogin {
UniversalResponse uniresp = new UniversalResponse();
private Boolean hasil = true ;
public Boolean getHasil() {
return hasil;
}
public void setHasil(Boolean hasil) {
this.hasil = hasil;
}
public Boolean authorize(String user, String passwd){
APIInterface apiInterface;
LoginModel logindata = new LoginModel();
logindata.setUsername(user);
logindata.setPassword(passwd);
apiInterface = APIClient.getClient().create(APIInterface.class);
//Call&lt;UniversalResponse&gt; call = apiInterface.doLogin(logindata.getUsername(), logindata.getPassword());
Call&lt;UniversalResponse&gt; call = apiInterface.doLogin(user, passwd);
call.enqueue(new Callback&lt;UniversalResponse&gt;() {
@Override
public void onResponse(Call&lt;UniversalResponse&gt; call, Response&lt;UniversalResponse&gt; response)
{
UniversalResponse uniresp = response.body();
Log.d(&quot;Login Module - Value dr Hasil sebelum Reponse Successfull&quot; , getHasil().toString());
if(response.isSuccessful() ) {
Log.d(&quot;Nama Service&quot;, uniresp.getService());
Log.d(&quot;Isi Message&quot;, uniresp.getMessage());
Log.d(&quot;Login Module - Value dr Hasil di DALAM Reponse Successfull&quot; , getHasil().toString());
if ( uniresp.getMessage().equals(&quot;Success&quot;) &amp;&amp; uniresp.getService().equals(&quot;MobileAppLogin&quot;) )
{
setHasil(true);
Log.d(&quot;Login Module - Value dr Hasil di DALAM Reponse Successfull dlm If Getmessasge Equals&quot; , getHasil().toString());
}
else {  setHasil(false);
Log.d(&quot;Login Module - Value dr Hasil di DALAM Reponse Successfull dlm If Getmessasge Equals Equals ELSE Section&quot; , getHasil().toString());   }
}
Log.d(&quot;Login Module - Value dr Hasil di LUAR Reponse Successfull&quot; , getHasil().toString());
}
@Override
public void onFailure(Call&lt;UniversalResponse&gt; call, Throwable t) {
call.cancel();
hasil= false;
}
});
Log.i(&quot;Login Module - Value dr Hasil di DEKAT RETURN PALING BAWAH&quot; , getHasil().toString());
return getHasil();
}
}

答案1

得分: 0

很不幸,您编写代码的方式并不总是有效。这是一个典型的异步任务被当作同步任务运行的情况。

hasil 的值在 onFailureonResponse 内部被改变,这可能在您从 authorize 方法返回之前就没有机会完成。

为了让这个工作起来,您需要改变传播 hasil 值到调用代码的方式。有几种方法可以做到这一点,其中一种不会对您的代码进行太多更改的简单方法是使用回调:

interface Callback {
  void onResponse(boolean hasil);

  void onError(Throwable t);
}

现在,您不需要从 authorize 函数返回,而是需要将这个回调传递进来:

public void authorize(String user, String passwd, Callback callback){
   // ...
   call.enqueue(new Callback<UniversalResponse>() {
        @Override
        public void onResponse(Call<UniversalResponse> call, Response<UniversalResponse> response)
        {
           if(response.isSuccessful() ) {
                if ( uniresp.getMessage().equals("Success") && uniresp.getService().equals("MobileAppLogin") )
                {
                    callback.onResponse(true);
                }
                else {  callback.onResponse(false);  }
            }
        }

        @Override
        public void onFailure(Call<UniversalResponse> call, Throwable t) {
           callback.onError(t);
        }
    });
}

这个思路是不返回任何内容,让调用您代码的人在登录操作成功或失败时得到通知。注意,这正是您在使用 call.enqueue 时实现的方式。

正如我提到的,还有其他处理这个问题的方法。我认为这个方法可能是引入更少改变的方法之一。

英文:

Unfortunately, the way you wrote your code won't always work. This is the classic case of an asynchronous task being run as a synchronous one.

The value of hasil is changed inside onFailure and onResponse which may not have a chance to finish before you return from the method authorize.

You need to change the way you're propagating the value of hasil to the calling code in order to be able to get this to work. There are several ways of doing so, one easy way without introducing too many changes to your code is to have a callback:

interface Callback {
void onResponse(boolean hasil);
void onError(Throwable t);
}

Now instead of returning from the fuction authorize you need to pass this callback in:

public void authorize(String user, String passwd, Callback callback){
// ...
call.enqueue(new Callback&lt;UniversalResponse&gt;() {
@Override
public void onResponse(Call&lt;UniversalResponse&gt; call, Response&lt;UniversalResponse&gt; response)
{
if(response.isSuccessful() ) {
if ( uniresp.getMessage().equals(&quot;Success&quot;) &amp;&amp; uniresp.getService().equals(&quot;MobileAppLogin&quot;) )
{
callback.onResponse(true);
}
else {  callback.onResponse(false);  }
}
}
@Override
public void onFailure(Call&lt;UniversalResponse&gt; call, Throwable t) {
callback.onError(t);
}
});
}

The idea is to not return anything and let whoever is calling your code get notified of the result of the login operation when the login operation fails or succeeds. Notice, this is exactly how you've implemented your retrofit call with call.enqueue.

As I mentioned, there are other ways to deal with this. I think this one is potentially the one that introduces fewer changes.

huangapple
  • 本文由 发表于 2020年9月11日 16:33:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/63843549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定