在安卓系统中使用改造

2022-09-01 00:16:16

我有一个机器人应用程序,有3个活动:

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

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

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

如果我的应用程序是一个单一的活动应用程序,我会处理我的MainActivity中的所有内容.java但我不知道如何以及在哪里放置步骤1,2,3中的所有代码以用于我的3个活动。你能不能通过告诉如何在我的应用程序中使用改造来提供帮助。多谢。

具体来说,我需要网络调用: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();
            }
        });
    }

答案 1

使用改造非常简单明了。

首先,您需要将改造添加到项目中,例如Gradle构建系统。

compile 'com.squareup.retrofit:retrofit:1.7.1' |

另一种方法可以下载.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);

}

还行。现在,您已经定义了 API 接口,可以尝试使用它。

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

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

YourUsersApi yourUsersApi = restAdapter.create(YourUsersApi.class);

在这里,改造将从界面读取您的信息,在引擎盖下,它将根据您提供的元信息创建RestHandler,这些信息实际上将执行HTTP请求。

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

要扩展/重写序列化器/反序列化过程,您可能需要提供自定义序列化器/反序列化器以进行改造。

在这里,您需要实现转换器接口并实现来自Body()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);
       }
    }
 }

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

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

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

SomeUserModel yourUser = yourUsersApi.fetchUser("someUsers")

以获取远程数据。


答案 2

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

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

第一件事是您需要在应用程序中添加改造,有2种方法,请按照上面的@artemis帖子进行操作。

改造使用接口作为您的 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

}

创建另一个接口类来保存 API 的所有基址

public interface Constants{
   public String URL = "www.yoururl.com"
}

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

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
        }
    });
}

在您的主要活动列表中

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
        }
    });
}

在您的详细列表中

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
        }
    });
}

希望这能帮助你,虽然它确实是使用改造的最简单方法。


推荐