在Android中使用Retrofit

Sta*_*Man 41 java api android retrofit

我有一个Android应用程序,有3个活动:

  1. 登录活动
  2. 显示与用户相关的所有任务的任务活动(使用阵列适配器填充)
  3. 通过单击列表上的任务产生的task_details活动

我必须使用REST Apis.到目前为止,我所做的研究指导我使用Retrofit.我检查了如何使用它并发现:

  1. 在主要活动中设置基本URL(我的是登录活动)
  2. 我需要创建一个API类并使用注释定义我的函数.
  3. 在Activity中使用Rest Adapter类并定义Callbacks.

如果我的应用程序是一个单独的活动应用程序,我会在我的MainActivity.java中捣乱一切,但我不知道如何以及在何处将步骤1,2,3中的所有代码用于我的3个活动中.请问你好吗通过告诉如何在我的应用程序中使用Retrofit来提供帮助.非常感谢.

具体来说,我需要网络呼叫:1.登录用户2.获取用户的所有任务.对于两者,我将使用给定的REST api.

*********************************************
          Calling Api USing Retrofit
*********************************************
**Dependancies** :-
      implementation 'com.android.support:recyclerview-v7:27.1.1'
        implementation 'com.squareup.picasso:picasso:2.5.2'
        implementation 'com.android.support:cardview-v7:27.1.1'
    enter code here
**Model**
use the Pozo class

**Api Call**
 -> getLogin()    // use the method



  //API call for Login
    private void getLogin()
    {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
        AsyncHttpClient client = new AsyncHttpClient();
        RequestParams requestParams = new RequestParams();
        requestParams.put("email_id", edit_email.getText().toString());
        requestParams.put("password", edit_password.getText().toString());
        Log.e("", "LOGIN URL==>" + Urls.LOGIN + requestParams);
        Log.d("device_token", "Device_ Token" + FirebaseInstanceId.getInstance().getToken());
        client.post(Urls.LOGIN, requestParams, new JsonHttpResponseHandler() {
            @Override
            public void onStart() {
                super.onStart();
                ShowProgress();
            }

            @Override
            public void onFinish() {
                super.onFinish();
                Hideprogress();

            }

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                super.onSuccess(statusCode, headers, response);
                Log.e("", "Login RESPONSE-" + response);
                Login login = new Gson().fromJson(String.valueOf(response), Login.class);
                edit_email.setText("");
                edit_password.setText("");
                if (login.getStatus().equals("true")) {
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                    MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("User Login Successfully!"),
                            MDToast.LENGTH_SHORT, MDToast.TYPE_SUCCESS);
                    mdToast.show();
                    Utils.WriteSharePrefrence(SignInActivity.this, Util_Main.Constant.EMAIL, login.getData().getEmailId());
                    Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERID, login.getData().getId());

                    Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERNAME, login.getData().getFirstName());
                    Utils.WriteSharePrefrence(SignInActivity.this, Constant.PROFILE, login.getData().getProfileImage());
                    hideKeyboard(SignInActivity.this);
                    Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);
                    finish();
                } else {
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                    MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("Login Denied"),
                            MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
                    mdToast.show();
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                super.onFailure(statusCode, headers, responseString, throwable);
                Log.e("", throwable.getMessage());
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
                MDToast mdToast = MDToast.makeText(SignInActivity.this, "Something went wrong",
                        MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
                mdToast.show();
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

Art*_*mis 97

使用Retrofit非常简单明了.

首先,您需要为项目添加改造,例如使用Gradle构建系统.

compile 'com.squareup.retrofit:retrofit:1.7.1' |
Run Code Online (Sandbox Code Playgroud)

另一种方法是你可以下载.jar并将它放到你的libs文件夹中.

然后,您需要定义将由Retrofit用于对REST端点进行API调用的接口.例如对于用户:

public interface YourUsersApi {

   //You can use rx.java for sophisticated composition of requests 
   @GET("/users/{user}")
   public Observable<SomeUserModel> fetchUser(@Path("user") String user);

   //or you can just get your model if you use json api
   @GET("/users/{user}")
   public SomeUserModel fetchUser(@Path("user") String user);

   //or if there are some special cases you can process your response manually 
   @GET("/users/{user}")
   public Response fetchUser(@Path("user") String user);

}
Run Code Online (Sandbox Code Playgroud)

好.现在您已经定义了API接口,您可以尝试使用它.

首先,您需要创建一个RestAdapter实例并设置API后端的基本URL.它也很简单:

RestAdapter restAdapter = new RestAdapter.Builder()
   .setEndpoint("https://yourserveraddress.com")
    .build();

YourUsersApi yourUsersApi = restAdapter.create(YourUsersApi.class);
Run Code Online (Sandbox Code Playgroud)

这里Retrofit将从界面读取您的信息,它将根据您提供的实际将执行HTTP请求的元信息创建RestHandler.

接下来,一旦收到响应,在json api的情况下,您的数据将使用Gson库转换为您的模型,因此您应该意识到Gson中存在的限制实际上存在于Retrofit中.

要将您的响应数据扩展/覆盖序列化程序/反序列化到您的模型,您可能需要提供自定义序列化程序/解串器以进行改进.

在这里,您需要实现Converter接口并实现fromBody()toBody()的 2个方法.

这是一个例子:

public class SomeCustomRetrofitConverter implements Converter {

    private GsonBuilder gb;

    public SomeCustomRetrofitConverter() {
        gb = new GsonBuilder();

        //register your cursom custom type serialisers/deserialisers if needed
        gb.registerTypeAdapter(SomeCutsomType.class, new SomeCutsomTypeDeserializer());
    }

    public static final String ENCODING = "UTF-8";

    @Override
    public Object fromBody(TypedInput body, Type type) throws ConversionException {
        String charset = "UTF-8";
        if (body.mimeType() != null) {
            charset = MimeUtil.parseCharset(body.mimeType());
        }
        InputStreamReader isr = null;
        try {
           isr = new InputStreamReader(body.in(), charset);
           Gson gson = gb.create();
           return gson.fromJson(isr, type);
        } catch (IOException e) {
            throw new ConversionException(e);
        } catch (JsonParseException e) {
            throw new ConversionException(e);
        } finally {
            if (isr != null) {
                   try {
                      isr.close();
                   } catch (IOException ignored) {
                }
            }
        }
    }

    @Override
    public TypedOutput toBody(Object object) {
        try {
            Gson gson = gb.create();
            return new JsonTypedOutput(gson.toJson(object).getBytes(ENCODING), ENCODING);
        } catch (UnsupportedEncodingException e) {
            throw new AssertionError(e);
        }
     }

    private static class JsonTypedOutput implements TypedOutput {
        private final byte[] jsonBytes;
        private final String mimeType;

        JsonTypedOutput(byte[] jsonBytes, String encode) {
            this.jsonBytes = jsonBytes;
            this.mimeType = "application/json; charset=" + encode;
        }

        @Override
        public String fileName() {
            return null;
        }

       @Override
       public String mimeType() {
           return mimeType;
       }

       @Override
       public long length() {
          return jsonBytes.length;
       }

       @Override
       public void writeTo(OutputStream out) throws IOException {
           out.write(jsonBytes);
       }
    }
 }
Run Code Online (Sandbox Code Playgroud)

现在,如果需要在构建RestAdapter时使用setConverter(),则需要启用自定义适配器

好.现在您知道如何将数据从服务器提供到Android应用程序.但是你需要以某种方式管理你的数据并在正确的位置调用REST调用.在那里我建议使用android Service或AsyncTask或loader或rx.java来查询后台线程上的数据,以便不阻止你的UI.

所以现在你可以找到最合适的地方

SomeUserModel yourUser = yourUsersApi.fetchUser("someUsers")
Run Code Online (Sandbox Code Playgroud)

获取远程数据.

  • `未解决的参考:RestAdapter`看来在版本2中不再使用RestAdapter.这个问题有助于解释:http://stackoverflow.com/questions/32424184/restadapter-retrofit-not-resolving-in-android (2认同)

chk*_*km8 24

我刚刚使用了改装几周,起初我发现在我的应用中很难使用.我想与您分享在您的应用程序中使用改造的最简单方法.如果你已经很好地掌握了改造,那么稍后你可以增强你的代码(将你的ui与api分开并使用回调),也许从上面的帖子中获得一些技巧.

在您的应用程序中,您有登录,任务列表的活动和查看详细任务的活动.

首先,您需要在您的应用中添加改造,并且有两种方式,请按照上面的@artemis帖子进行操作.

Retrofit使用interface作为您的API.所以,创建一个接口类.

public interface MyApi{

/*LOGIN*/
@GET("/api_reciever/login") //your login function in your api
public void login(@Query("username") String username,@Query("password") String password,Callback<String> calback); //this is for your login, and you can used String as response or you can use a POJO, retrofit is very rubust to convert JSON to POJO

/*GET LIST*/
@GET("/api_reciever/getlist") //a function in your api to get all the list
public void getTaskList(@Query("user_uuid") String user_uuid,Callback<ArrayList<Task>> callback); //this is an example of response POJO - make sure your variable name is the same with your json tagging

/*GET LIST*/
@GET("/api_reciever/getlistdetails") //a function in your api to get all the list
public void getTaskDetail(@Query("task_uuid") String task_uuid,Callback<Task> callback);   //this is an example of response POJO - make sure your variable name is the same with your json tagging

}
Run Code Online (Sandbox Code Playgroud)

创建另一个接口类来保存api的所有BASE ADDRESS

public interface Constants{
   public String URL = "www.yoururl.com"
}
Run Code Online (Sandbox Code Playgroud)

在您的登录活动中,创建一个处理改造的方法

private void myLogin(String username,String password){

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)  //call your base url
    .build();


MyApi mylogin = restAdapter.create(MyApi.class); //this is how retrofit create your api
mylogin.login(username,password,new Callback<String>() {
        @Override
        public void success(String s, Response response) {
            //process your response if login successfull you can call Intent and launch your main activity

        }

        @Override
        public void failure(RetrofitError retrofitError) {
            retrofitError.printStackTrace(); //to see if you have errors
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在您的MainActivityList中

private void myList(String user_uuid){

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)  //call your base url
    .build();


MyApi mytask = restAdapter.create(MyApi.class); //this is how retrofit create your api
mytask.getTaskDetail(user_uuid,new Callback<Task>>() {
        @Override
        public void success(ArrayList<Task> list, Response response) {
            //process your response if successful load the list in your listview adapter

        }

        @Override
        public void failure(RetrofitError retrofitError) {
            retrofitError.printStackTrace(); //to see if you have errors
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在您的详细清单中

private void myDetailed(String task_uuid){

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(Constants.URL)  //call your base url
    .build();


MyApi mytask = restAdapter.create(MyApi.class); //this is how retrofit create your api
mytask.getTaskList(task_uuid,new Callback<Task>() {
        @Override
        public void success(Task task, Response response) {
            //process your response if successful do what you want in your task

        }

        @Override
        public void failure(RetrofitError retrofitError) {
            retrofitError.printStackTrace(); //to see if you have errors
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助你,虽然它真的是最简单的改造方式.

  • Retrofit是一个用于android的REST api,基本上你需要有一个服务器端应用程序,比如php,你还需要构建你的api.如果你还没有尝试创建与Android的REST简单的移动应用程序,你可能会与本​​教程开始,HTTP://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-和源码/.如果您已经拥有REST经验,那么Retrofit将是一个很好的库. (2认同)
  • 它实际上不是一个php页面.它应该是一个api,通常是普通的PHP脚本,它接受像JSON/XML格式的POST/GET之类的请求.这是api的一个例子.function login_post(){$ email = $ this-> post('email'); $ password = $ this-> post('password'); $ data = $ this-> Auth_model-> authenticate($ email,$ password); 的print_r($数据); } (2认同)