I can't save data loaded from okhttp. What is wrong in my code. When I try to load data on Log app crashes. Please Help.
public class MainActivity extends AppCompatActivity {
private static final String URL = "https://chroniclingamerica.loc.gov/search/titles/results/?terms=michigan&format=json&page=5";
private String data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
Log.d("DATA", data);
}
private void loadData() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
data = response.body().string();
}
});
}
}
Explanation
The problem is around how your code is being executed (i.e sync vs async).
You call the method loadData() which will not set the class attribute data as you're expecting - it will set the attribute data once it gets a response however that function loadData will not wait for the response (i.e it doesn't block the current thread or execution code.) . Which means on the next line LOG.d("Data", data);, data has not been set, thus is null (and will crash your app).
Solution
If you just want to LOG data, then just move your log statement after you assign it on your onResponse callback.
private void loadData() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// Some error has occurred
}
#Override
public void onResponse(Call call, Response response) throws IOException {
processData(response.body().string());
}
});
}
private void processData(String data) {
Log.d("DATA", data);
// To other stuff here given your value data.
}
Related
I'm trying to make an application to work with the SMS distribution
service API. To send a message, I need to complete a curl request
https://email:api_key#gate.smsaero.ru/v2/sms/send?numbers[]=79990000000&numbers[]=79990000001&text=your+text&sign=SMS Aero&channel=DIRECT
How can this be implemented in Android?
This may works
public void send(String url) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
call.cancel();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
How to connect Web socket API to android application or any 3rd party library is required? any know know this concept please post
You can use okhttp3 on Android to handle WebSockets!
Example code:
public class EchoWebSocketListener extends WebSocketListener {
#Override public void onOpen(WebSocket webSocket, Response response) {
// called when the connection is opened
}
#Override public void onMessage(WebSocket webSocket, String text) {
//...
}
#Override public void onMessage(WebSocket webSocket, ByteString bytes) {
//...
}
#Override public void onClosing(WebSocket webSocket, int code, String reason){
//...
}
#Override public void onFailure(WebSocket webSocket, Throwable t, Response response){
//...
}
}
Then, in your Activity:
#Override protected onCreate(Bundle savedInstance){
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url("ws://echo.websocket.org").build();
EchoWebSocketListener listener = new EchoWebSocketListener();
WebSocket ws = client.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
}
I want to send a message from Android okhttp3 websocket client, not just echoing the messages coming from the server. here is my websocket class:
// Websocket
public final class EchoWebSocketListener extends WebSocketListener {
private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
webSocket.send(message);
}
#Override
public void onMessage(WebSocket webSocket, String text) {
printer("text");
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
}
public void send(WebSocket webSocket) {
webSocket.send(finalMessage);
}
}
And here is how I call it from the onCreate method:
client= new OkHttpClient();
Request request = new Request.Builder().url(Url).build();
EchoWebSocketListener listener = new EchoWebSocketListener();
webso = myClient.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
I tried to make an object to the class and call a function I named it 'send':
EchoWebSocketListener object = new EchoWebSocketListener ()
object.send(webso)
But that's not working?
recommend you this way RxWebSocket
My interface
#POST("/insert.php")
void login(Callback<Response> callback);
Java code
Retrofit adapter = new Retrofit.Builder()
.baseUrl(ROOT_URL) //Setting the Root URL
.addConverterFactory(GsonConverterFactory.create())
.build(); //Finally building the adapter
Register_Retrofit api = adapter.create(Register_Retrofit.class);
api.login( new Callback<Response>() {
public void onResponse(Call<Response> call, Response<Response> response) {
}
public void onFailure(Call<Response> call, Throwable t) {
}
});
Your login method return void, so you need to define it like this:
#POST("/insert.php")
Call<Void> login();
Then, to call the login method try this:
Retrofit adapter = new Retrofit.Builder()
.baseUrl(ROOT_URL) //Setting the Root URL
.addConverterFactory(GsonConverterFactory.create())
.build(); //Finally building the adapter
Register_Retrofit api = adapter.create(Register_Retrofit.class);
Call<Void> loginCall = api.login();
loginCall.enqueue(new Callback<Void>() {
public void onResponse(Call<Void> call, Response<Void> response) {
...
}
public void onFailure(Call<Void> call, Throwable t) {
...
}
});
In my android application I have to do some http request using android volley. If my request succeed everything's ok, the problem arise when I get an error and this error has status code 401. In this case I want to make some stuff and repeat the same request, same url and same parameters. Is there an official way to do that? If not, how can I get my params from error?
StringRequest req = new StringRequest(method, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response){
//VolleyLog.v("Response:%n %s", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
if(response.statusCode == 401){
//make some stuff...
//here i want to resend my request
}
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
//get headers
}
#Override
public Map<String, String> getParams() throws AuthFailureError {
//get params
}
};
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
Any help would be appreciated.
You can create the RetryPolicy to change default retry behavior, only specify timeout milliseconds, retry count arguments :
public class YourRequest extends StringRequest {
public YourRequest(String url, Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(url, listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
}
the another way is estimate the VolleyError, re-execute the same request again when if was TimeoutError instance :
public static void executeRequest() {
RequestQueue.add(new YourRequest("http://your.url.com/", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError) {
// note : may cause recursive invoke if always timeout.
executeRequest();
}
}
}));
}
Hope this will help you
After modifying the request add the request in requestQueue.
Do it in ErrorListener.