I have this issue with Volley library requests. I make calls to API and since they have to be updated very often I implemented timers. After some time it throws me error:"Throwing OutOfMemoryError “pthread_create (1040KB stack) failed: Try again. I used the method which was suggested in this post: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again" when doing asynchronous posts using Volley , but for me it did not work, the data coming from API stopped updating. I thought it might be something with timers or it is just something I am doing wrong using Volley.
If you have any idea, feel welcome to share.
My printer class
public void setMenuInformation(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
if (eRequestQueue == null) {
eRequestQueue = Volley.newRequestQueue(context);
eRequestQueue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String temp = response.substring(2, response.length() - 2);
Log.d("API", "Current menu" + response);
byte msgArray[];
try {
msgArray = temp.getBytes("ISO-8859-1");
currentMenu = msgArray[0];
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
menuInformation = response;
callback.onSuccess(menuInformation);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "Current menu Nope ");
callback.onFailure(error);
}
}));
}
}
Main Activity:
myPrinterDetails.setMenuInformation("http://" + nsdServiceInfo.getHost() + "/GetCurrentMenu",
MainActivity.this, new PrinterNew.VolleyCallback() {
#Override
public void onSuccess(String result) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d("NSD", "Current menu response succeded and added to array " + nsdServiceInfo);
//services.add(myPrinterDetails);
mAdapter.notifyDataSetChanged();
}
});
Log.d("NSD", "CurrentMenu " + myPrinterDetails.getMenuInformation());
myTimer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
myPrinterDetails.setMenuInformation("http://" + nsdServiceInfo.getHost() + "/GetCurrentMenu", MainActivity.this, new PrinterNew.VolleyCallback() {
#Override
public void onSuccess(String result) {
Log.d("NSD", "Current menu response added to timer " + nsdServiceInfo);
mAdapter.notifyDataSetChanged();
}
#Override
public void onFailure(Object response) {
Log.d("NSD", "Current menu timer failed");
}
});
}
});
}
}, 0, 2000);
}
#Override
public void onFailure(Object response) {
Log.d("NSD", "Current menu response failed");
}
});
}
};
}
Related
I am creating app that can run 2 process at the time (saving to database / sending to api) but , i was encountering issue from my treading.This is my code upon my threading:
this is my code:
public void timerToSaveSend() {
Thread t1 = new Thread() {
#Override
public void run() {
saving();
}
};
t1.start();
Thread t2 = new Thread(){
#Override
public void run() {
sending();
}
};
t2.start();
}
private void sending() {
//dataSendApi
handler10 = new Handler();
handler10.postDelayed(new Runnable() {
#Override
public void run() {
try {
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl("http://" + ADDRESS + ":" + PORT)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
API locate = retrofit.create(API.class);
Call<MapDetails> call = locate.mapDetailLocation(data);
call.enqueue(new Callback<MapDetails>() {
#Override
public void onResponse(Call<MapDetails> call,
Response<MapDetails> response) {
String portString = String.valueOf(portss);
}
#Override
public void onFailure(Call call, Throwable t) {
Log.d("Message: ", "Data not sent, please check your
network connection.");
}
});
} catch (Exception e) {
Toast.makeText(NavDrawerFleet.this, "Disconnected from Internet, Please Configure Settings", Toast.LENGTH_SHORT).show();
restFailed();
}
}
}, 10000);
}
private void saving() {
//4SECOND
handler2 = new Handler();
handler2.postDelayed(new Runnable() {
#Override
public void run() {
DatabaseHelper databaseHelper = new DatabaseHelper(getApplicationContext());
SQLiteDatabase db = databaseHelper.getWritableDatabase();
well2 = String.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", java.util.Locale.getDefault()).format(new java.util.Date()));
boolean accepted = databaseHelper.saveLocationToLocalDatabase(gg, hidelat.getText().toString(), hidelon.getText().toString(), well2, "1", "9090", db);
failedCount.setText(String.valueOf(retryList.size()));
lat2 = hidelat.getText().toString();
lon2 = hidelon.getText().toString();
MapDetails mapDetails = new MapDetails(gg, hidelat.getText().toString(), hidelon.getText().toString(), well2, "1", 9090);
data.add(mapDetails);
retry2 = new NotSentModuleGetterSetter(hidelat.getText().toString(), hidelon.getText().toString(), well2);
retryList.add(retry2);
retrylist_adapter.notifyDataSetChanged();
if (accepted == true)
Log.w("Data Entered: ", "1st Copy");
}
}, 2000);
saving();
}
and this is my error encountered:
PS. I was wondering that my code is to totally not working though i want also other possible code implementation with this one, like asynctask to work with this multiple process + with threading in a single meathod.
For threading, please consider using RxJava. It would be as simple as this
Observable.fromCallable(new Callable<Object>() {
#Override public Object call() throws Exception {
saving();
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Object>() {
#Override public void onSubscribe(Disposable d) {
}
#Override public void onNext(Object o) {
}
#Override public void onError(Throwable e) {
}
#Override public void onComplete() {
}
});
Check this link out on how to integrate RxJava into your project https://github.com/ReactiveX/RxAndroid
I want to add progressdialog into okhttp (asynchronous, not AsyncTask)
but i got this error:
Error: Can't create handler inside thread that has not called
Looper.prepare()
How to fix it in a proper way? I want to be sure that is the best way to do this.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("TAG_response", " brak neta lub polaczenia z serwerem ");
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
progress = ProgressDialog.show(SignUp.this, "dialog title",
"dialog message", true);
try {
Log.d("TAGx", response.body().string());
if (response.isSuccessful()) {
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
//System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
Log.d("TAG2", responseHeaders.name(i));
Log.d("TAG3", responseHeaders.value(i));
}
Log.d("TAG", response.body().string());
progress.dismiss();
main_activity();
}
else{
progress.dismiss();
alertUserAboutError();
}
}
catch (IOException e){
Log.d("TAG", "error");
}
}
});
OkHttp runs the onResponse method on the same background thread which it does the http call on. Because you're doing an async call this means it will not be the Android main thread.
To run code on the main thread from onResponse you can use a Handler and Runnable:
client.newCall(request).enqueue(new Callback() {
Handler handler = new Handler(SignUp.this.getMainLooper());
#Override
public void onFailure(Call call, IOException e) {
//...
}
#Override
public void onResponse(Call call, Response response) throws IOException {
handler.post(new Runnable() {
#Override
public void run() {
// whatever you want to do on the main thread
}
});
}
To begin with, I checked literally every single SwipeToRefreshLayout question to solve this issue, but none worked for me. So I'm asking for your help to solve this issue.
I want the refresher to go away "once the refreshing is complete". What I tried so far either made it go away too early, or not go away at all. Here is the related code: (note that mSwipeRefreshLayout is already defined.)
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
final double latitude = 39.9179;
final double longitude = 32.8627;
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
handler.post(refreshing);
getForecast(latitude, longitude);
}
});
getForecast(latitude, longitude);
}
private final Runnable refreshing = new Runnable(){
public void run(){
try {
if(mSwipeRefreshLayout.isRefreshing()){
handler.postDelayed(this, 500);
}else{
mSwipeRefreshLayout.setRefreshing(false);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
};
and the data fetch function:
private void getForecast(double latitude, double longitude) {
String apiKey = "7d22cdb138cd70f2e9e8d2006cd0461c";
String forecastUrl = "https://api.forecast.io/forecast/" + apiKey
+ "/" + latitude + "," + longitude;
if (isNetworkAvailable()){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(forecastUrl).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
alertUserAboutError();
}
#Override
public void onResponse(Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mCurrentWeather = getCurrentDetails(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
} else {
alertUserAboutError();
}
} catch (IOException e) {
Log.e(TAG, "Exception caught: ", e);
} catch (JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});
}
else {
Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show();
}
}
swipeContainer = (SwipeRefreshLayout) v.findViewById(R.id.swipeContainer);
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
getForecast(latitude, longitude); //call ur function here
swipeContainer.setRefreshing(false);
}
});
I'm developing a simple WebSocket in Android using AndroidAsync library:
http://www.koushikdutta.com/AndroidAsync
My Client code:
private void conectar() {
//String uri = "ws://192.167.101.142:1234";
String uri = "http://192.167.101.166:1234";
AsyncHttpClient asyncHttpClient = AsyncHttpClient.getDefaultInstance();
//asyncHttpClient.websocket(new AsyncHttpGet(uri), "my-protocol", new AsyncHttpClient.WebSocketConnectCallback() {
//asyncHttpClient.websocket(uri, "https", new AsyncHttpClient.WebSocketConnectCallback() {
//asyncHttpClient.websocket(new AsyncHttpGet(uri), null, new AsyncHttpClient.WebSocketConnectCallback() {
//asyncHttpClient.websocket(new AsyncHttpGet(uri), "SSL", new AsyncHttpClient.WebSocketConnectCallback() {
asyncHttpClient.websocket(uri, null, new AsyncHttpClient.WebSocketConnectCallback() {
#Override
public void onCompleted(Exception ex, WebSocket webSocket) {
Log.e(TAG, "webSocket is null");
Log.e(TAG, "Metodo onCompleted");
if (ex != null) {
Log.e(TAG, ex.getMessage(), ex);
return;
}
//Log.e(TAG, "webSocket.isOpen(): " + webSocket.isOpen());
webSocket.send("a string");
webSocket.send(new byte[10]);
webSocket.setStringCallback(new WebSocket.StringCallback() {
public void onStringAvailable(String s) {
System.out.println("I got a string: " + s);
Log.e(TAG, "I got a string: " + s);
//showToast("I got a string: " + s);
}
});
webSocket.setDataCallback(new DataCallback() {
#Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList byteBufferList) {
System.out.println("I got some bytes!");
Log.e(TAG, "I got some bytes!");
// note that this data has been read
byteBufferList.recycle();
}
});
}
});
}
My Server code:
private void conectar() {
AsyncHttpServer server = new AsyncHttpServer();
server.listen(PORTA);
server.get("/", new HttpServerRequestCallback() {
#Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
response.send("Hello!!!");
}
});
server.websocket("/", new AsyncHttpServer.WebSocketRequestCallback() {
#Override
public void onConnected(final WebSocket webSocket, AsyncHttpServerRequest request) {
Log.e(TAG, "Metodo: onConnected");
_sockets.add(webSocket);
//Use this to clean up any references to your websocket
webSocket.setClosedCallback(new CompletedCallback() {
#Override
public void onCompleted(Exception ex) {
Log.e(TAG, "Metodo onCompleted from webSocket object");
try {
if (ex != null)
Log.e("WebSocket", "Error");
} finally {
_sockets.remove(webSocket);
}
}
});
webSocket.setStringCallback(new WebSocket.StringCallback() {
#Override
public void onStringAvailable(String s) {
Log.e(TAG, "Metodo onStringAvailable from webSocket object");
if ("Hello Server".equals(s))
webSocket.send("Welcome Client!");
}
});
}
});
Anyone knows tell me why Can't I connect my server?
I have tested the server code in another app websocket tester from google play.
The app server it's Ok.
However I cannot connect from my client app?
I'm using retrofit to add a task.
private void addTask(Map<String, String> map) {
ApiClient.getPptApiClient().addTask(map, new Callback<String>() {
#Override
public void success(String s, Response response) {
Log.d("TAG", "add task success");
downloadTasks(id)
}
#Override
public void failure(RetrofitError retrofitError) {
Log.d("TAG", "add task failed");
}
});
}
after add task succes i want to refresh my list, and for that i have method below:
private void downloadTasks(int id) {
ApiClient.getPptApiClient().getTasks(id, new Callback<ArrayList<TaskModel>>() {
#Override
public void success(ArrayList<TaskModel> taskModels, Response response) {
Log.d("TAG", "download task success");
taskAdapter.clear();
taskAdapter.addAll(taskModels);
lvTasks.setAdapter(taskAdapter);
}
#Override
public void failure(RetrofitError retrofitError) {
Log.e("TAG", "download task failed");
}
});
}
My problem is : downloadTask is never called.
Can you explain why?