How to solve Retrofit2 interface null pointer - java

i try to connect my server and i stuck here about 3 hours. Simply use this in another project but... anyway here is my interface and service generator. Please help me...
ServiceGenerator
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ServiceGenerator {
private ServiceInterface serviceInterface;
private String BASE_URL = "http://xxxxxxxxx.com/xxxxx/xxx/";
public ServiceInterface init() {
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build();
serviceInterface = retrofit.create(ServiceInterface.class);
return serviceInterface;
}
public ServiceInterface getServiceInterface() {
return serviceInterface;
}
}
SevrviceInterface
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface ServiceInterface {
#GET("login.php")
Call<LoginResponse> login(#Query("UserName") String id,
#Query("Password") String pass,
#Query("token") String token
);
}
xxxxxxApp
import android.app.Application;
import com.xxxxxxxxxxxxx.network.ServiceGenerator;
import com.xxxxxxxxxxxxx.network.ServiceInterface;
public class xxxxxxApp extends Application {
private static xxxxxxApp instance;
private ServiceGenerator serviceGenerator = new ServiceGenerator();
public static xxxxxxApp getInstance() {
return instance;
}
#Override
public void onCreate() {
super.onCreate();
instance = this;
serviceGenerator.init();
}
public ServiceInterface getServiceInterface() {
return serviceGenerator.getServiceInterface();
}
}
LoginAct.java
public class LoginAct extends BaseActivity {
SharedPreferences preferences;
Button btn_login;
EditText edt_username;
EditText edt_pass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_login);
btn_login = findViewById(R.id.login_btn_login);
edt_username = findViewById(R.id.lgn_et_username);
edt_pass = findViewById(R.id.lgn_et_pass);
btn_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
xxxxxxApp.getInstance().getServiceInterface().login(edt_username.getText().toString(),edt_pass.getText().toString(),"").enqueue(new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()){
LoginAct.super.showToast(LoginAct.this," UserID : "+response.body().getUsers().get(0).getUser_ıd());
}
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
}
});
}
});
}
}
And if you cath my url doesn't have SSL its http:// . My error says :
java.lang.NullPointerException: Attempt to invoke virtual method 'com.xxxxxxxxxxxxxxxx.network.ServiceInterface com.xxxxxxxxxxxxxxxx.xxxxxxApp.getServiceInterface()' on a null object reference
at com.xxxxxxxxxxxxxxxx.ui.LoginAct$1.onClick(LoginAct.java:40)
I can't figure out how to solve this i try everything i can. please help.
.
.
.
.
.
.
.
.

Set your base url into
private String BASE_URL = "http://xxxxxxxxx.com/xxxxx";
and interface into
#GET("/xxx/login.php")
Call<LoginResponse> login(#Query("UserName") String id,
#Query("Password") String pass,
#Query("token") String token
);

Related

Retrofit Get Data Object

I have a data like this, and i want get report and criteria data.
{
"response_code": 200,
"message": "Your report data has been loaded.",
"data": {
"report": [
{
"id_report": 1,
"report_name": "report name A"
},
{
"id_report": 2,
"report_name": "report name B"
}
],
"criteria": [
{
"id_criteria": 1,
"criteria_name": "criteria name A"
},
{
"id_criteria": 2,
"criteria_name": "criteria name B"
}
]
}
}
And i get data in java using retrofit. And this is my java class.
GetReport.java
#SerializedName("response_code")
private int response_code;
#SerializedName("status")
private boolean status;
#SerializedName("message")
private String message;
#SerializedName("data")
Call<Data> listData;
Data.java
#SerializedName("report")
private List<Report> reportList;
#SerializedName("criteria")
private List<Criteria> criteriaList;
And this how i call the data.
public void populateData() {
Call<GetReport> getReportCall = apiInterface.getReportCall();
getReportCall.enqueue(new Callback<GetReport>() {
#Override
public void onResponse(Call<GetReport> call, Response<GetReport> response) {
response.body().getListData().enqueue(new Callback<Data>() {
#Override
public void onResponse(Call<Data> call, Response<Data> response) {
List<Report> reportList = response.body().getReportList();
Log.d("TAGGGGGGGGGG", String.valueOf(reportList.size()));
}
#Override
public void onFailure(Call<Data> call, Throwable t) {
t.printStackTrace();
}
});
}
#Override
public void onFailure(Call<GetReport> call, Throwable t) {
t.printStackTrace();
}
});
}
When I run the program, my activity closes immediately. When I look at logcat, there is too much running log data so I can't see where the error is.
I have managed to attempt and solve your problem with the following code. I copied and pasted the JSON you provided above at JSONbin.io so that I can be able to call it using an API call. I did not modify the structure of the JSON at all.
App build.gradle
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
GetReport.java
package com.example.retrofitapp;
import com.google.gson.annotations.SerializedName;
public class GetReport {
#SerializedName("response_code")
int response_code;
#SerializedName("message")
String message;
#SerializedName("data")
Data data;
public int getResponse_code() {
return response_code;
}
public void setResponse_code(int response_code) {
this.response_code = response_code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}}
Data.java
package com.example.retrofitapp;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Data {
#SerializedName("report")
List<Report> reportList;
#SerializedName("criteria")
List<Criteria> criteriaList;
public List<Report> getReportList() {
return reportList;
}
public void setReportList(List<Report> reportList) {
this.reportList = reportList;
}
public List<Criteria> getCriteriaList() {
return criteriaList;
}
public void setCriteriaList(List<Criteria> criteriaList) {
this.criteriaList = criteriaList;
}}
Criteria.java
package com.example.retrofitapp;
import com.google.gson.annotations.SerializedName;
public class Criteria {
#SerializedName("id_criteria")
int id_criteria;
#SerializedName("criteria_name")
String criteria_name;
public Criteria(int id_criteria, String criteria_name) {
this.id_criteria = id_criteria;
this.criteria_name = criteria_name;
}
public int getId_criteria() {
return id_criteria;
}
public void setId_criteria(int id_criteria) {
this.id_criteria = id_criteria;
}
public String getCriteria_name() {
return criteria_name;
}
public void setCriteria_name(String criteria_name) {
this.criteria_name = criteria_name;
}}
Report.java
package com.example.retrofitapp;
import com.google.gson.annotations.SerializedName;
public class Report {
#SerializedName("id_report")
int id_report;
#SerializedName("report_name")
String report_name;
public Report(int id_report, String report_name) {
this.id_report = id_report;
this.report_name = report_name;
}
public int getId_report() {
return id_report;
}
public void setId_report(int id_report) {
this.id_report = id_report;
}
public String getReport_name() {
return report_name;
}
public void setReport_name(String report_name) {
this.report_name = report_name;
}}
RetrofitClient.java
package com.example.retrofitapp.api;
import com.google.gson.*;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
public static Retrofit retrofit;
public static Retrofit getRetrofitClient(String baseUrl){
if(retrofit==null){
Gson gson = new GsonBuilder().setLenient().create();
retrofit = new Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create(gson)).build();
}
return retrofit;
}}
Constants.java
package com.example.retrofitapp;
public class Constants {
public static String base_url = "https://api.jsonbin.io/";
}
Api.java
package com.example.retrofitapp.api;
import com.example.retrofitapp.GetReport;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Headers;
public interface Api {
#Headers("Secret-key:$2a$10$WxkkTylkdR7NwGSoPwrfy.Odxtj7MR2vDtYZBp9cOd0SaYGVRmhOm")
#GET("/b/5ff8172e63e86571a2e35639")
Call<GetReport> getReport();
}
MainActivity.java
package com.example.retrofitapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.example.retrofitapp.api.Api;
import com.example.retrofitapp.api.RetrofitClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//call method here
populateData();
}
private void populateData() {
Retrofit retrofit = RetrofitClient.getRetrofitClient(Constants.base_url);
Api api = retrofit.create(Api.class);
Call<GetReport> getReportCall = api.getReport();
//make asynchronous request
getReportCall.enqueue(new Callback<GetReport>() {
#Override
public void onResponse(Call<GetReport> call, Response<GetReport> response) {
if(response.code() == 200){
GetReport getReport = (GetReport) response.body();
//get response code
int responseCode = getReport.getResponse_code();
//get message
String message = getReport.getMessage();
//get data
Data data = getReport.getData();
//get reports(loop)
for(Report report : data.getReportList()){
//your report here
}
//get criteria(loop)
for(Criteria criteria : data.getCriteriaList()){
//your criteria here
}
}
}
#Override
public void onFailure(Call<GetReport> call, Throwable t) {
//do something if the request failed
}
});
}}
That is how I solved it.

How to parse json with retrofit on Android

I try to write app which parse decoding of abbreviations and frequency of their use. User input abbreviation, for example "kg". So, app should connect to "http://nactem.ac.uk/software/acromine/dictionary.py?sf=kg" and parse it.
What should model classes look like? Did I describe #Geth correctly in the interface? How can I get the list, I made an adapter, bind it to the list, but I'm not sure about getResponse ().
Interface:
public interface SService {
#GET("dictionary.py?")
Call<Example> getResponse(#Query("sf=") String searchString);
}
Retrofit client:
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
And addition class ApiUtils
public class ApiUtils {
public static final String BASE_URL = "http://nactem.ac.uk/software/acromine/";
public static SService getSOService() {
return RetrofitClient.getClient(BASE_URL).create(SService.class);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private ArrayList<Lf> elements = new ArrayList();
EditText editText1;
ElementAdapter stateAdapter;
ListView list;
private SService mService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText1 = (EditText) findViewById(R.id.edit_text);
mService = ApiUtils.getSOService();
list = (ListView) findViewById(R.id.fragment_list);
stateAdapter = new ElementAdapter(this, R.layout.list_item, elements);
list.setAdapter(stateAdapter);
}
public void loadAnswers() {
mService.getResponse(editText1.getText().toString()).enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
if(response.isSuccessful()) {
stateAdapter.updateAnswers(response.body().getLfs());
} else {
int statusCode = response.code();
// handle request errors depending on status code
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
}
});
}
public void activity_button(View view) {
//stateAdapter.clear();
loadAnswers();
}
}
UPD!!
All input data is an array: Array[Object{...}]. Right interface for parsing it:
public interface SService {
#GET("dictionary.py")
Call<List<Example>> getResponse(#Query("sf") String searchString);
}
So, we get with Call List with Example object (Only one object in this case).
Change the SService interface to the following,
public interface SService {
#GET("dictionary.py")
Call<Example> getResponse(#Query("sf") String searchString);
}

Retrofil Attempt to invoke interface method call on a null object [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am trying to get JSON data via http using Retrofit for Android I am getting the following error:
Attempt to invoke interface method 'retrofit2.Call com.webdealer.otexconnect.goldback.network.LoginServices.sendSMS(java.lang.String)' on a null object reference
Here are my classes.
Client
package com.webdealer.otexconnect.goldback.network;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by fazal on 3/13/18.
*/
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
public void getServies(){
// return RetrofitClient.getClient(BASE_URL).create(LoginServices.class);
}
}
Interface:
package com.webdealer.otexconnect.goldback.network;
import com.webdealer.otexconnect.goldback.utils.Login;
import com.webdealer.otexconnect.goldback.utils.Sms;
import org.json.JSONObject;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Path;
/**
* Created by fazal on 3/13/18.
*/
public interface LoginServices {
#FormUrlEncoded
#POST("login")
Call<Login> login(#Field("email") String email, #Field("password") String password);
#FormUrlEncoded
#POST("register-customer")
Call<JSONObject> signUp(#Field("name") String name,#Field("email") String email,#Field("phone_number") String phoneNumber, #Field("password") String password);#FormUrlEncoded
#POST("register-driver")
Call<JSONObject> signUpDriver(#Field("name") String name,#Field("email") String email,#Field("phone_number") String phoneNumber, #Field("password") String password);
#FormUrlEncoded
#POST("send-sms-code")
Call<Sms> sendSMS (#Field("phone_number") String phone_number);
}
Model:
package com.webdealer.otexconnect.goldback.utils;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Sms {
#SerializedName("status")
#Expose
private Boolean status;
#SerializedName("fourDigitCode")
#Expose
private String fourDigitCode;
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public String getFourDigitCode() {
return fourDigitCode;
}
public void setFourDigitCode(String fourDigitCode) {
this.fourDigitCode = fourDigitCode;
}
}
try {
mLoginServices.sendSMS("+923418007173").enqueue(new Callback<Sms>(){
#Override
public void onResponse(Call<Sms> call, Response<Sms> response) {
Toast.makeText(getApplicationContext(), mPhone, Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<Sms> call, Throwable t) {
Toast.makeText(getApplicationContext(),"Failed",Toast.LENGTH_LONG).show();
}
});
}catch (Exception ex){
Log.e("Error sms",ex.getMessage());
}
Your implementation needs to be created:
public class RetrofitClient {
private static LoginServices apiService;
public RetrofitClient(String baseUrl) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(LoginServices.class);
}
public LoginServices getServies(){
return apiService;
}
}
Now when you call the service you just need to do:
RetrofitClient client = new RetrofitClient(BASE_URL);
client.getServies().sendSMS("+923418007173").enqueue(new Callback<Sms>(){
#Override
public void onResponse(Call<Sms> call, Response<Sms> response) {
Toast.makeText(getApplicationContext(), mPhone, Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<Sms> call, Throwable t) {
Toast.makeText(getApplicationContext(),"Failed",Toast.LENGTH_LONG).show();
}
});

How do I get an item from POJO classes in Android?

I am trying to get a specific Item from an API in my android application.
Here is the JSON response of the api:
{
"response": {
"items": [
{
"episode_id": 9599548,
"type": "RECORDED",
"title": "Adabule muferad 100916",
"duration": 3165940,
"explicit": false,
"show_id": 1392538,
"author_id": 7725967,
"site_url": "https://www.spreaker.com/episode/9599548",
"image_url": "https://d1bm3dmew779uf.cloudfront.net/large/f390b915e356de35055d971be5110dcb.jpg",
"image_original_url": "https://d3wo5wojvuv7l.cloudfront.net/images.spreaker.com/original/f390b915e356de35055d971be5110dcb.jpg",
"published_at": "2016-10-09 11:01:48",
"download_enabled": true,
"waveform_url": "https://d3770qakewhkht.cloudfront.net/episode_9599548.gz.json?v=qB6pQ6"
}
],
"next_url": "https://api.spreaker.com/v2/users/7725967/episodes?filter=listenable&last_id=9599548&limit=1"
}
}
I have three Java classes Items, Response and RadioProgramInfo.
Here are their codes respectively:
Items.java
public class Items
{
public String duration;
public String title;
public String download_enabled;
public String image_original_url;
public String image_url;
public String explicit;
public String episode_id;
public String author_id;
public String show_id;
public String type;
public String waveform_url;
public String published_at;
public String site_url;
public String getDuration ()
{
return duration;
}
public void setDuration (String duration)
{
this.duration = duration;
}
public String getTitle ()
{
return title;
}
public void setTitle (String title)
{
this.title = title;
}
public String getDownload_enabled ()
{
return download_enabled;
}
public void setDownload_enabled (String download_enabled)
{
this.download_enabled = download_enabled;
}
public String getImage_original_url ()
{
return image_original_url;
}
public void setImage_original_url (String image_original_url)
{
this.image_original_url = image_original_url;
}
public String getImage_url ()
{
return image_url;
}
public void setImage_url (String image_url)
{
this.image_url = image_url;
}
public String getExplicit ()
{
return explicit;
}
public void setExplicit (String explicit)
{
this.explicit = explicit;
}
public String getEpisode_id ()
{
return episode_id;
}
public void setEpisode_id (String episode_id)
{
this.episode_id = episode_id;
}
public String getAuthor_id ()
{
return author_id;
}
public void setAuthor_id (String author_id)
{
this.author_id = author_id;
}
public String getShow_id ()
{
return show_id;
}
public void setShow_id (String show_id)
{
this.show_id = show_id;
}
public String getType ()
{
return type;
}
public void setType (String type)
{
this.type = type;
}
public String getWaveform_url ()
{
return waveform_url;
}
public void setWaveform_url (String waveform_url)
{
this.waveform_url = waveform_url;
}
public String getPublished_at ()
{
return published_at;
}
public void setPublished_at (String published_at)
{
this.published_at = published_at;
}
public String getSite_url ()
{
return site_url;
}
public void setSite_url (String site_url)
{
this.site_url = site_url;
}
#Override
public String toString()
{
return "ClassPojo [duration = "+duration+", title = "+title+", download_enabled = "+download_enabled+", image_original_url = "+image_original_url+", image_url = "+image_url+", explicit = "+explicit+", episode_id = "+episode_id+", author_id = "+author_id+", show_id = "+show_id+", type = "+type+", waveform_url = "+waveform_url+", published_at = "+published_at+", site_url = "+site_url+"]";
}
}
Response.java
public class Response
{
private Items[] items;
private String next_url;
public Items[] getItems ()
{
return items;
}
public void setItems (Items[] items)
{
this.items = items;
}
public String getNext_url ()
{
return next_url;
}
public void setNext_url (String next_url)
{
this.next_url = next_url;
}
#Override
public String toString()
{
return "ClassPojo [items = "+items+", next_url = "+next_url+"]";
}
}
RadioProgramInfo.java
public class RadioProgramInfo
{
private Response response;
public Response getResponse ()
{
return response;
}
public void setResponse (Response response)
{
this.response = response;
}
#Override
public String toString()
{
return "ClassPojo [response = "+response+"]";
}
}
I am trying to access a specific Item called "site_url" which is located in Items.java
The code in my main class to try to access site_url is this:
Items url2 = new Items();
String streamURL = String.valueOf(url2)+"/shoutcast?force_http=true";
// new HttpRequestTask().execute();
// return true;
String url = "http://api.spreaker.com/listen/episode/9451446/shoutcast?force_http=true";
//String url2 = Items.class.getName(site_url);
public MainActivity() {
}
//System.out.println(streamURL);
public class HttpRequestTask extends AsyncTask<Void, Void, Items> {
protected Items doInBackground(Void... params) {
try {
final String url = String.valueOf(streamURL);
RestTemplate restTemplate = new RestTemplate();
//restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Items streamlink = restTemplate.getForObject(url, Items.class);
return streamlink;
}
catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return url2;
}
}
When I run my program (a media player app):
It tells me that the url is null in value (I debug mode on the program as it executes).
How do I correctly access the item in the JSON response I am after?
I am really stuck on this one.
---UPDATE-----
Here is the response from the console:
10-09 15:25:39.522 2586-2647/software.blackstone.com.salafimasjidradioseries E/MainActivity: 'messageConverters' must not be empty
java.lang.IllegalArgumentException: 'messageConverters' must not be empty
at org.springframework.util.Assert.notEmpty(Assert.java:269)
at org.springframework.web.client.HttpMessageConverterExtractor.<init>(HttpMessageConverterExtractor.java:53)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:235)
at software.blackstone.com.salafimasjidradioseries.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:46)
at software.blackstone.com.salafimasjidradioseries.MainActivity$HttpRequestTask.doInBackground(MainActivity.java:39)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
.... and the complete MainActivity Code is this:
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
static MediaPlayer mPlayer;
ImageButton buttonPlay;
ImageButton buttonStop;
Items url2 = new Items();
String streamURL = String.valueOf(url2)+"/shoutcast?force_http=true";
// new HttpRequestTask().execute();
// return true;
String url = "http://api.spreaker.com/listen/episode/9451446/shoutcast?force_http=true";
//String url2 = Items.class.getName(site_url);
public MainActivity() {
}
//System.out.println(streamURL);
public class HttpRequestTask extends AsyncTask<Void, Void, Items> {
protected Items doInBackground(Void... params) {
try {
final String url = String.valueOf(streamURL);
RestTemplate restTemplate = new RestTemplate();
//restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Items streamlink = restTemplate.getForObject(url, Items.class);
return streamlink;
}
catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return url2;
}
}
#Override
protected void onStart() {
super.onStart();
new HttpRequestTask().execute();
}
i admittedly don't have any experience using Spring libraries for mobile development. there are, however, several other popular libraries at your disposal that are typically used to accomplish your goal.
below is an example i whipped using your DTO classes. i added these dependencies via my app's build.gradle:
compile 'com.squareup.okhttp:okhttp:2.7.5'
compile 'com.google.code.gson:gson:2.4'
OkHttp is a library for creating + executing HTTP requests
Gson is a library for (un)marshaling data as json
the code should be pretty self-explanatory. i've just plugged in the bits to do my HTTP GET and marshal the data into the DTO within the AsyncTask.
public class MainActivity extends AppCompatActivity {
private MediaPlayer mPlayer = new MediaPlayer();
private OkHttpClient client = new OkHttpClient();
private Gson gson = new Gson();
public class HttpRequestTask extends AsyncTask<Void,Void,Items[]> {
protected Items[] doInBackground(Void... params) {
final Request request = new Request.Builder()
.url("https://api.myjson.com/bins/1z98u")
.build();
Items[] items = null;
try {
final com.squareup.okhttp.Response response = client.newCall(request).execute();
if(response.isSuccessful()) {
final RadioProgramInfo radioProgramInfo = gson.fromJson(response.body().charStream(), RadioProgramInfo.class);
items = radioProgramInfo.getResponse().getItems();
} else {
throw new RuntimeException("ooops!");
}
} catch (Throwable t) {
Log.e("MainActivity", t.getMessage(), t);
}
return items;
}
#Override
protected void onPostExecute(Items[] items) {
try {
mPlayer.setDataSource(items[0].getSite_url());
mPlayer.prepareAsync();
} catch(IOException e) {
e.printStackTrace();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
new HttpRequestTask().execute();
}
}
hope that helps!
Since youre not really sure what to use and are currently using Spring, I'd recommend you to take a look at Retrofit which does exactly what you are looking for. It has very good documentation and a lot of examples of exactly what you're trying to do.. Here's a pretty good introduction to it: square.github.io/retrofit

Updating class field from callback

I'm trying to connect to API using Retrofit. I need to login user and after this set "user" field which contains session key which is required to all other api calls. So I need to have it available before executing any code but I don't know how to check or block code until this field will be set. Any ideas how to do it?
public class ApiClient {
public static final String developerKey = "";
public static final String applicationKey = "";
static final String BASE_URL =
"https://secure.techfortesco.com/tescolabsapi";
public ApiService mApiService;
public User user;
public ApiClient() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel( RestAdapter.LogLevel.FULL )
.setEndpoint( BASE_URL )
.build();
if(mApiService == null) {
mApiService = restAdapter.create( ApiService.class );
}
}
public void login() {
mApiService.login( developerKey, applicationKey, new Callback<User>() {
#Override
public void success ( User user, Response response ) {
//code which should update user field
}
#Override
public void failure ( RetrofitError error ) {
}
} );
}
public interface ApiService {
#GET ("/restservice.aspx?command=LOGIN&email=&password=")
public void login (
#Query ("developerkey") String developerKey,
#Query ("applicationkey") String applicationKey,
Callback<User> callback );
#GET ("/restservice.aspx?command=PRODUCTSEARCH")
public void search (
#Query ("searchtext") String searchText,
#Query ("sessionkey") String sessionKey,
Callback<Pojo.SearchResult> callback);
}
}
You can try using callback:
Example:
public interface LoginCallback {
void ready();
}
And in the Activity / Fragment
public MainActivity extends Activity {
public void onCreate() {
super.onCreate();
ApiClient client = new ApiClient();
client.login(new LoginCallback() {
#Override
public void ready() {
//... do your next request in the API.
}
});
}
}
and your login method became:
public void login(final LoginCallback loginCallback) {
mApiService.login( developerKey, applicationKey, new Callback<User>() {
#Override
public void success ( User user, Response response ) {
//code which should update user field
loginCallback.ready();
}
#Override
public void failure ( RetrofitError error ) {
}
} );
}

Categories

Resources