2014-10-22 5 views
40

У меня есть андроид приложение, которое имеет 3 вида деятельности:Использование Дооснащение в Android

  1. Войти деятельность
  2. задачи acivity, где отображаются все задачи, относящиеся к пользователю (Заполняется с помощью массива адаптера)
  3. Task_details активность, которая возникает при нажатии задачи в списке

Я должен использовать REST Apis. Исследование, которое я сделал до сих пор, направляет меня на использование Retrofit. Я проверил, как использовать его и выяснил, что:

  1. Установите базовый URL в основной деятельности (Mine это Войти активность)
  2. Мне нужно создать класс API и определять свои функции с помощью аннотаций.
  3. Используйте Адаптер отдыха класса в Управлении и определите Обратные вызовы.

Если бы мое приложение было одним активным приложением, я бы все хрустел в своей MainActivity.java, но я не знаю, как и где поставить весь код из шагов 1,2,3 для использования в моем 3 действия. Не могли бы вы помочь, рассказав, как использовать Retrofit в моем приложении. Большое спасибо.

В частности, мне нужны сетевые вызовы: 1. Войдите в систему пользователя 2. Получите все задачи пользователя. И для обоих я использовал бы данный REST api.

+6

Я не нахожу достаточно документации/учебников для использования Модернизации. –

+1

Вы поняли это? –

+0

лучше использовать залп для быстрой работы в сети. – Dev

ответ

91

Использование Дооснащение довольно прост и понятен.

Прежде всего, вам необходимо добавить модификацию в проект, например, с помощью системы сборки Gradle.

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

другой способ вы можете скачать .jar и поместить его в свою папку с папками.

Затем вам необходимо определить интерфейсы, которые будут использоваться Retrofit для вызова API для ваших конечных точек REST. Например, для пользователей:

public interface YourUsersApi { 

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

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

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

} 

Ok. Теперь вы определили свой интерфейс API, и можете попробовать его использовать.

Для начала вам нужно создать экземпляр RestAdapter и установить базовый адрес вашего API фоновым. Это также довольно просто:

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

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

Здесь дооснащения будет читать информацию из интерфейса и под капотом он будет создавать RestHandler согласно мета-информации ваши предоставленные которые фактически будут выполнять запросы HTTP.

Затем под капотом, после получения ответа, в случае json api ваши данные будут преобразованы в вашу модель с использованием библиотеки Gson, поэтому вы должны знать об этом факте, что ограничения, которые присутствуют в Gson, действительно присутствуют в Retrofit ,

Чтобы продлить/переопределить процесс сериализации/десериализации ваших данных ответа на ваши модели, вы можете захотеть предоставить свои пользовательские сериализаторы/десеризаторы для модернизации.

Здесь вам нужно реализовать интерфейс конвертер и реализовать 2 метода fromBody() и toBody().

Вот пример:

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

И теперь вам нужно активировать пользовательские адаптеры, если это было необходимо с помощью setConverter() на строительство RestAdapter

Ok. Теперь вы знаете, как вы можете получать свои данные с сервера на свое приложение для Android. Но вам нужно как-то сжать ваши данные и вызвать звонок REST в нужном месте. Там я бы предложил использовать службу android Service или AsyncTask или загрузчик или rx.java, которые будут запрашивать ваши данные в фоновом потоке, чтобы не блокировать ваш пользовательский интерфейс.

Итак, теперь вы можете найти наиболее подходящее место, чтобы позвонить

SomeUserModel yourUser = yourUsersApi.fetchUser("someUsers") 

принести удаленные данные.

+2

'Unresolved reference: RestAdapter' Появляется RestAdapter больше не используется в версии 2. Этот вопрос помог объяснить, что: http://stackoverflow.com/questions/32424184/restadapter-retrofit-not-resolving-in-android –

+0

это дооснащение 1. Люди сейчас используют модификацию 2. синтаксис отличается. –

4

Посмотрите на этот отличный блог об использовании Retrofit в сочетании с Otto, обе библиотеки находятся на площади.

http://www.mdswanson.com/blog/2014/04/07/durable-android-rest-clients.html

Основная идея заключается в том, что вы будете держать ссылку на «хранилище» объекта в классе Application. Этот объект будет иметь методы, которые «подписываются» на отдых для запросов api-событий. Когда один из них будет получен, он сделает правильный повторный выбор, а затем «отправит» ответ, который затем может быть «подписан» другим компонентом (например, деятельностью, которая сделала запрос).

После того, как вы все правильно настроите, доступ к данным через ваш api для отдыха станет очень простым. Например, делая это запрос данных будет выглядеть примерно так:

mBus.post(new GetMicropostsRequest(mUserId)); 

и потребляющих данные будут выглядеть примерно так:

@Subscribe 
public void onGetUserProfileResponse(GetUserProfileResponse event) { 
    mView.setUserIcon("http://www.gravatar.com/avatar/" + event.getGravatar_id()); 
    mView.setUserName(event.getName()); 

} 

Это занимает немного авансовый усилий, но в конец становится «тривиальным» для доступа к чему-либо, что вам нужно, из нашего бэкэнда через Rest.

2

Во-первых, положить все в MainActivity будет плохой практикой, и вы получите в итоге God object.

Документация на Retrofit site является фантастической, поэтому я собираюсь прочитать ваш вопрос о том, как структурировать проект. Я написал очень маленькое приложение для демонстрационных целей.Он загружает кошек из API кошки и должен быть довольно простым, чтобы следить за тем, что происходит.

В нем есть пример использования JSON или XML для анализа данных из службы. Вы можете найти его на https://github.com/codepath/android_guides/wiki/Consuming-APIs-with-Retrofit

Надеюсь, вы сможете экстраполировать, почему я структурировал его так, как я. Я рад ответить на любые ваши вопросы в комментариях и обновить ответ.

2

Оформить заказ на это приложение, которое демонстрирует интеграцию дооснащения Google API задач.

https://github.com/sschendel/SyncManagerAndroid-DemoGoogleTasks

Есть примеры Retrofit API (TaskApi), используемые в деятельности AsyncTask в MainActivity, а также примеры использования в синхронизации адаптера в фоновом режиме службы.

Стратегия из статьи, опубликованной в ответе @ nPn, вероятно, является более элегантным решением, но вы можете хотя бы взглянуть на другой рабочий пример.

24

Я только что использовал модификацию в течение нескольких недель, и сначала мне было трудно использовать ее в моем приложении. Я хотел бы поделиться с вами самым простым способом использования модификации в вашем приложении. И затем, если вы уже хорошо разбираетесь в модернизации, вы можете улучшить свои коды (отделяя ui от api и использовать обратные вызовы) и, возможно, получить некоторые методы из поста выше.

В вашем приложении у вас есть Вход, активность для списка задач и активность для просмотра подробной задачи.

Первое, что вам нужно, чтобы добавить модификацию в ваше приложение, а theres 2 пути, следуйте за сообщением @artemis выше.

Retrofit использует интерфейс как ваш 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 

} 

Создайте еще один класс интерфейса, чтобы держать все ваши базовый адрес вашего апи

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

В вашем 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 
     } 
    }); 
} 

В Вашем подробного списке

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

Надеется, что это поможет вам, хотя его на самом деле самый простой способ использования переоснащения.

+1

Извините, если мой вопрос очень тривиален, но я действительно пытаюсь начать использовать Retrofit (но нулевой прогресс). Должны ли мы иметь что-то вроде php-страницы для выполнения этой задачи? – mok

+2

Retrofit - это REST api для android, в основном вам нужно иметь приложение на стороне сервера, например php, где вам также понадобится построить api. Если вы havent пытались создать простое мобильное приложение с REST в android, вы можете начать с этого учебника, http: //www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql- и-SQLite /. И если у вас уже есть опыт в REST, Retrofit будет хорошей библиотекой для использования. – chkm8

+0

Спасибо. Действительно, я уже пробовал это, и я это понимаю. Вы создаете страницу php, которая получает то, что вы отправили как POST, и генерирует ответ в формате JSON. У вас что-нибудь даже близко к этому учебнику для переоснащения? – mok

3

Вы можете попробовать сохранить ссылки на свой api внутри вашего класса приложений. Затем вы можете получить экземпляр из любой активности или фрагмента и получить api оттуда. Это звучит немного странно, но это может быть простая альтернатива DI. И если вы будете хранить только ссылки в своем классе приложения, это не будет своего рода объект бога

UPD: http://square.github.io/retrofit/ - вот некоторые документы, это может быть полезно

3

Использование ДООСНАСТКЕ очень легко.

  • Добавить dependecy в build.gradle.

    compile 'com.squareup.retrofit:retrofit:1.9.0' 
    
        compile 'com.squareup.okhttp:okhttp:2.4.0' 
    
  • Сделать интерфейс для всех методов http.

  • Скопируйте выход JSon и создать класс Pojo, чтобы получать JSON вашего
    ответа, вы можете сделать POJO с JsonSchema2pojo сайта.

  • сделать переходник и вызвать ваш метод

    для полной демонстрации попробовать этот учебник Retrofit Android example

2

Я нахожу эти учебники AndroidHive, полезные

Я кратко описать то, что я узнал ,

Шаг 1: Добавить эти три dependencies to build.gradle и добавить Internet permission в Manifest

compile 'com.google.code.gson:gson:2.6.2' // for string to class conversion. Not Compulsory 
compile 'com.squareup.retrofit2:retrofit:2.1.0'// compulsory 
compile 'com.squareup.retrofit2:converter-gson:2.1.0' //for retrofit conversion 

Добавьте их в манифесте

<uses-permission android:name="android.permission.INTERNET" /> 

Шаг 2 Creae ApiClient и ApiInterface.

public class ApiClient { 

    public static final String BASE_URL = "http://yourwebsite/services/"; 
    private static Retrofit retrofit = null; 

    public static Retrofit getClient() { 
     if (retrofit==null) { 
      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 
     } 
     return retrofit; 
    } 
} 

где ApiInterface.class

public interface ApiInterface { 

    // getting same data in three different ways. 
    @GET("GetCompanyDetailByID") 
    Call<CompanyResponse> getDetailOfComapanies(@Query("CompanyID") int companyID); 


    @GET("GetCompanyDetailByID") 
    Call<ResponseBody> getRawDetailOfCompanies(@Query("CompanyID") int companyID); 

    @GET("{pathToAdd}") 
    Call<CompanyResponse> getDetailOfComapaniesWithPath(@Path("pathToAdd") String pathToAppend, @Query("CompanyID") int companyID); 
} 

И называют эту услугу, как

ApiInterface apiService = 
       ApiClient.getClient().create(ApiInterface.class); 

     Call<CompanyResponse> companyResponseCall = apiService.getDetailOfComapanies(2); 
     //Call<CompanyResponse> companyResponseCall = apiService.getDetailOfComapaniesWithPath("GetCompanyDetailByID",2); 

     companyResponseCall.enqueue(new Callback<CompanyResponse>() { 
      @Override 
      public void onResponse(Call<CompanyResponse> call, Response<CompanyResponse> response) { 
       CompanyResponse comapnyResponse = response.body(); 
       Boolean status = comapnyResponse.getStatus(); 
      } 

      @Override 
      public void onFailure(Call<CompanyResponse> call, Throwable t) { 
      } 
     }); 

Для Получение Raw Json Строка

Call<ResponseBody> call = apiService.getRawDetailOfCompanies(2); 
     call.enqueue(new Callback<ResponseBody>() { 
      @Override 
      public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
        String jsonStr = response.body().string(); 
        if(!jsonStr.isEmpty()){ 
         Gson gson = new Gson(); 

         JSONObject jObject = new JSONObject(jsonStr).getJSONObject("data"); 

         //1st Method 
         Data dataKiType = gson.fromJson(jObject.toString(), Data.class); 
         dataKiType.getCompanyDetail(); 

         //2nd method for creaing class or List at runTime 
         Type listType = new TypeToken<Data>(){}.getType(); 
         Data yourClassList = new Gson().fromJson(jObject.toString(), listType); 
         yourClassList.getCompanyDetail(); 
        } e.printStackTrace(); 
       } 
      } 

      @Override 
      public void onFailure(Call<ResponseBody> call, Throwable t) { 
      } 
     }); 

Вы можете создать свой бизнес-объект, используя http://www.jsonschema2pojo.org/, просто вставив json. и выбор типа источника для JSON и стиля аннотации для GSon

1

Начинающие находят, что это немного пугает, чтобы изучить модернизацию. Я подготовил учебник, который упростит кривую обучения. См. Retrofit android tutorial для получения дополнительной информации.

0

Его Рабочая

enter image description here пакет com.keshav.gmailretrofitexampleworking.network;

import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 

public class ApiClient { 
    public static final String BASE_URL = "http://api.androidhive.info/json/"; 
    private static Retrofit retrofit = null; 

    public static Retrofit getClient() { 
     if (retrofit == null) { 
      retrofit = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 
     } 
     return retrofit; 
    } 
} 
============================================== 
package com.keshav.gmailretrofitexampleworking.network; 

import com.keshav.gmailretrofitexampleworking.models.Message; 

import java.util.List; 

import retrofit2.Call; 
import retrofit2.http.GET; 

public interface ApiInterface { 
    @GET("inbox.json") 
    Call<List<Message>> getInbox(); 
} 

compile 'com.google.code.gson: gson: 2.6.2'

compile 'com.squareup.retrofit2:retrofit:2.0.2' 

compile 'com.squareup.retrofit2:converter-gson:2.0.2' 

========================================= ============

Вызов дооснащения 2 APi внутри OnCreate

private void getInbox() { 
    swipeRefreshLayout.setRefreshing(true); 

    ApiInterface apiService = 
      ApiClient.getClient().create(ApiInterface.class); 

    Call<List<Message>> call = apiService.getInbox(); 
    call.enqueue(new Callback<List<Message>>() { 
     @Override 
     public void onResponse(Call<List<Message>> call, Response<List<Message>> response) { 
      // clear the inbox 
      messages.clear(); 

      // add all the messages 
      // messages.addAll(response.body()); 

      // TODO - avoid looping 
      // the loop was performed to add colors to each message 

      Log.e("keshav","response" +response.body()); 

      for (Message message : response.body()) { 
       // generate a random color 

       // TODO keshav Generate Random Color Here 
       message.setColor(getRandomMaterialColor("400")); 
       messages.add(message); 
      } 

      mAdapter.notifyDataSetChanged(); 
      swipeRefreshLayout.setRefreshing(false); 
     } 

     @Override 
     public void onFailure(Call<List<Message>> call, Throwable t) { 
      Toast.makeText(getApplicationContext(), "Unable to fetch json: " + t.getMessage(), Toast.LENGTH_LONG).show(); 
      swipeRefreshLayout.setRefreshing(false); 
     } 
    }); 
} 

Исходный код https://drive.google.com/open?id=0BzBKpZ4nzNzUVFRnVVkzc0JabUU

https://drive.google.com/open?id=0BzBKpZ4nzNzUc2FBdW00WkRfWW8

0

Разработка собственной HTTP-библиотеки, защищенной типами, для взаимодействия с REST API может быть настоящей болью: вам необходимо обрабатывать многие аспекты, такие как создание соединений, кэширование, повторная попытка неудачных запросов, потоковая обработка, анализ ответов, обработка ошибок и многое другое. С другой стороны, дооснащение - это хорошо спланированная, документированная и проверенная библиотека, которая сэкономит вам много драгоценного времени и головных болей.

компиляция 'com.google.code.gson: gson: 2.6.2'

компиляции 'com.squareup.retrofit2: Модифицированный: 2.1.0' // обязательного

компиляция «ком. squareup.retrofit2: конвертер-gson: 2.1.0' // для преобразования модифицированной

0

во-первых, добавьте эти строки в Gradle файлу

compile 'com.squareup.retrofit2:retrofit:2.1.0' 
    compile 'com.squareup.retrofit2:converter-gson:2.1.0' 
    compile 'com.google.code.gson:gson:2.7' 
    compile 'com.squareup:otto:1.3.8' 
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1' 

Затем Создание объектов в OnCreate деятельности

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);  
OkHttpClient client= new OkHttpClient 
       .Builder() 
       .connectTimeout(30, TimeUnit.SECONDS) 
       .readTimeout(30, TimeUnit.SECONDS) 
       .addInterceptor(interceptor).build(); 
Gson gson=new GsonBuilder() 
      .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") 
      .create(); 
Retrofit retrofit= new Retrofit.Builder() 
       .baseUrl("url") 
       .client(client) 
       .addConverterFactory(GsonConverterFactory.create(gson)) 
       .build(); 

Создать iterface

public interface summaryListAPI { 
//post 
    @FormUrlEncoded 
    @POST("index.php") 
    Call<summaryList> post(
      @Field("status") String status, 
      @Field("sox") String sox 
    ); 
//get 
@GET("yesbdeChatHistoryList/{userId}/") 
    Call<List<ChatTabTwoResp>> getFriends(
      @Path("userId") int userId 
    ); 
} 

Создать классы

public class summaryList { 
    @SerializedName("bookingSummary") @Expose private List<summaryListData> status = new ArrayList<summaryListData>(); 
} 

public class summaryListData { 
    @SerializedName("date") @Expose private String date; 
} 

Добавить этот метод в вашей деятельности

public void apiSummaryListMain(final Retrofit retrofit) { 
     retrofit.create(summaryListAPI.class).post("8547861657","100").enqueue(new Callback<summaryList>() { 
      @Override 
      public void onResponse(Call<summaryList> call, Response<summaryList> response) { 
       if (response.isSuccessful()) { 
        progressBar.setVisibility(View.INVISIBLE); 
        List<summaryListData> summary_List= response.body().getStatus();     
       }else{    
       } 
      } 
      @Override 
      public void onFailure(Call<summaryList> call, Throwable t) { 

      } 
     }); 

    } 
0

Я просто тормозил эту проблему в очень простым способом вы просто нужно установить плагин и следующие шаги по реализации переоснащения в любой из ваших App .:

Уже отправил ответ: Retrofit in android?

Добавить (QAssist - Android-студия Plugin) Android плагин в вашем Android студии. (https://github.com/sakkeerhussain/QAssist).

Надеюсь, это вам поможет.

Смежные вопросы