I've always been curious about implementing Retrofit in my applications to make simple POST and GET requests. However I have have problems wrapping my head around it. Today I decided to try to integrate it in my app but am having troubles. If you could have a look at my code that would be great. This is the error I'm getting
"Caused by: retrofit.RetrofitError: retrofit.converter.ConversionException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2"
This is the api call if you want to try it out.
http://api.thebookofeveryone.com/social/makelove?phrase=love
I also know I'm not doing anything with the returned Image Object right now as I need to solve this problem first.
Thank you.
MainActivity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
extraThread task = new extraThread();
task.execute();
}
public class extraThread extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
RetrofitInterface.getImageApiClient().getImage("love");
return null;
}
}
RetroFit Interface
public class RetrofitInterface {
private static ImageApiInterface sImageService;
public static ImageApiInterface getImageApiClient() {
if (sImageService == null) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://api.thebookofeveryone.com")
.build();
sImageService = restAdapter.create(ImageApiInterface.class);
}
return sImageService;
}
public interface ImageApiInterface {
#GET("/social/makelove")
Image getImage(#Query("phrase") String phrase);
}
}
Image Class
public class Image {
boolean success;
String url;
}
It's a JSON parsing error. Change you Image class to:
public class Image {
private Boolean success;
private String url;
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Or:
public class Image {
Boolean success;
String url;
}
Everything should work fine.
To create a POJO from JSON or JSON-Schema, I recommend http://www.jsonschema2pojo.org/. It's really helpful.
Related
I was testing the API in the Retrofit for first time, I was putting the code that they were showing but I don't know why my code doesn't work
it just shows that I am receiving the null value;
I was learning to implement the Retrofit library in my android app . so i was following some tutorial and i was following the code but don't know why i am getting this error
i tried to solve the error by changing the url but the response is the same it shows the null.
Please help me out
public class Todo {
private int userId;
private int id;
private String todo;
private boolean completed;
public int getUserId() {
return userId;
}
public int getId() {
return id;
}
public String getTitle() {
return todo;
}
public boolean isCompleted() {
return completed;
}
}
public interface ApiInterface {
#GET("/todo/{id}")
Call<Todo> getTodo(#Path("id") int id);
}
public class ApiClient {
private static final String BASE_URL ="https://dummyjson.com";
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;
}
public class MainActivity extends AppCompatActivity {
TextView hello;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hello= findViewById(R.id.textview);
ApiInterface apiInterface = ApiClient.getclient().create(ApiInterface.class);
Call<Todo> call =apiInterface.getTodo(1);
call.enqueue(new Callback<Todo>() {
#Override
public void onResponse(Call<Todo> call, Response<Todo> response) {
Log.e("info","onResponse"+response.body());
#Override
public void onFailure(Call<Todo> call, Throwable t) {
Log.e("info","onFailure" + t.getLocalizedMessage());
}
});
}
}
You are missing the plural 's' in todo. Change your path to #GET("/todos/{id}")
What is the proper way in the following code (it's a bit complicated structure to me) to get url from the method gotUrl() to the doInBackground() method of AsyncTask in order to use it in onPostExecute(), after the doInBackground() method has completed its task?
public class PlayerActivity extends CustomActivity implements
ProblemListener{
public class PlayChannel extends
AsyncTask<CustomChangeChannel, String, String> {
#Override
protected String doInBackground(CustomChangeChannel... params) {
initOctoshapeSystem();
return url;
}
#Override
protected void onPostExecute(String url){
}
}
public void initOctoshapeSystem() {
os = OctoStatic.create(this, this, null);
os.setOctoshapeSystemListener(new OctoshapeSystemListener() {
#Override
public void onConnect() {
mStreamPlayer = setupStream(OCTOLINK);
mStreamPlayer.requestPlay();
}
});
}
public StreamPlayer setupStream(final String stream) {
StreamPlayer sp = os.createStreamPlayer(stream);
sp.setStatusChangedListener(new StatusChangedListener() {
#Override
public void statusChanged(byte oldStatus,
final byte newStatus) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//todo
}
});
}
});
sp.setListener(new StreamPlayerListener() {
#Override
public void gotUrl(String url) {
//String to be passed
}
});
return sp;
}
}
AsyncTask<Param1, Param2, Param3>
Param 1 is the param that you pass into your doInBackground method.
Param 2 is what you want to get while the AsyncTask working.
Param 3 is what you want to get as result.
You can declare all them as Void.
AsyncTask<Void, Void, Void>
In your case you want to pass String URL to your doInBackground, so:
AsyncTask<String, Void, Void>
Pass your URL String when you call the execute.
mAsyncTask.execute("your url");
Then get it in the doInBackground:
protected Void doInBackground(String... params) {
String yourURL = params[0];
return null;
}
change this
public class PlayChannel extends
AsyncTask<CustomChangeChannel, String, String>
to this
public class PlayChannel extends
AsyncTask<String, String, String>
and then use
PlayChannel channel = new PlayChannel(url);
I am using retrofit library for a web service that expect request as json and give response as json.
public class GitHubClient extends Activity{
private static final String API_URL = "http://10.0.0.32/test";
static class Contributor {
String login;
int contributions;
}
public static class Array {
public String id;
public String name;
}
class Contributor1 {
public Array array;
}
interface Login {
#POST("/testapp/")
Contributor1 mu(#Body User user,Callback<Contributor1> callBack);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new myasyncclass().execute();
}
public class User {
public String mail;
public String password;
}
public class myasyncclass extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// Create a very simple REST adapter which points the GitHub API endpoint.
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer(API_URL)
.build();
Login login = restAdapter.create(Login.class);
User user=new User();
user.mail="ttete";
user.password="tett";
Contributor1 contributors = login.mu(user,new Callback<Contributor1>() {
#Override
public void failure(RetrofitError error) {
System.out.println("failure, error: " + error);
}
#Override
public void success(Contributor1 result, Response arg1) {
System.out.println("success, result: " + result);
}
});
return null;
}
}
}
This is my entire class .But i am getting the following error
Caused by: java.lang.IllegalArgumentException: Method mu may only have return type or Callback as last argument, not both.
What should i do overcome this error?
This interface definition is wrong as per the error.
interface Login {
#POST("/testapp/")
Contributor1 mu(#Body User user,Callback<Contributor1> callBack);
}
You should modify it to
interface Login {
#POST("/testapp/")
Contributor1 mu(#Body User user);
}
Since now it does not have a callback, you should be able to call it synchronously.
I want to do background tasks in Android to send a request to an API, but I can't get it to work the way I want.
These are my scripts:
Activity class
public class SampleActivity extends Activity {
private ApiRequest ar;
private String parameters;
...
private void callApi() {
this.ApiRequest = new ApiRequest(this.parameters);
}
}
ApiRequest class
public class ApiRequest {
private String response;
public ApiRequest(parameters) {
new BackgroundTask().execute(parameters);
}
protected class BackgroundTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... args) {
// Do stuff here
}
#Override
protected void onPostExecute(String response) {
this.response = response;
}
}
Somehow, I can't seem to update the response string from the onPostExecute method. I know onPostExecute is supposed to update the UI thread, but I want to update the object first, which essentially runs in the UI thread (I think). How is this done? I can't find anything about it really.
#Override
protected void onPostExecute(String response) {
this.response = response;
}
In this scope, this refers to the instance of BackgroundTask and NOT to ApiRequest. I'm surprised your code even compiles.
Change it to ApiRequest.this.response = response.
I would like to pass a single string into an asynctask. Could anyone show me how it is done? my getEntity needs The method getEntity(Activity, String, EntityGetListener) but I keep passing this String[]
String pass= story.get(position).getEntity();
new RemoteDataTask().execute(pass);
private class RemoteDataTask extends AsyncTask<String, String, Long> {
#Override
protected Long doInBackground(String... params) {
// TODO Auto-generated method stub
EntityUtils.getEntity(activity, params, new EntityGetListener() {
#Override
public void onGet(Entity entity) {
viewcount = entity.getEntityStats().getViews();
}
#Override
public void onError(SocializeException error) {
}
});
return null;
}
}
You already have this
new RemoteDataTask().execute(pass); // assuming pass is a string
In doInbackground
#Override
protected Long doInBackground(String... params) {
String s = params[0]; // here's youre string
... //rest of the code.
}
You can find more info #
http://developer.android.com/reference/android/os/AsyncTask.html
Update
Asynctask is depecated. Should be using kotlin coroutines or rxjava or any other threading mechanism as alternatives.
You can build AsyncTask with a constructor.
public class RemoteDataTask extends AsyncTask<String, String, Long> {
private String data;
public RemoteDataTask(String passedData) {
data = passedData;
}
#Override
protected String doInBackground(Context... params) {
// you can access "data" variable here.
EntityUtils.getEntity(activity, params, new EntityGetListener() {
#Override
public void onGet(Entity entity) {
viewcount = entity.getEntityStats().getViews();
}
#Override
public void onError(SocializeException error) {
}
});
return null;
}
}
In the application (Activity, Service etc), you can use;
private RemoteDataTask mTask;
private void doStuff(){
String pass = "meow"; // story.get(position).getEntity();
mTask = new RemoteDataTask(pass);
mTask.execute();
}