I want to restart my service with new data, what allows me to release every objects in service without making complicated communication between Fragment<>Service.
I tried this, everything works:
if(isMyServiceRunning(PlayerService.class))
{
getActivity().stopService(intenx);
positionTemp--;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
getActivity().startService(intenx);
positionTemp++;
}
}, 500);
}
else{
getActivity().startService(intenx);
}
}
});
But I don't know if I should to worry about closing time in different devices? Is there possibility than service will be closing longer than 500ms? My Motorola takes 300ms to close service and then I can re-run it without problem.
Any advice? Communication with service isn't really easy, it's music player with almost 15 different controls, etc. I think that the easiest way is just stop current service and restart with new entry variables.
That seems unnecessary, and it'll add a 500 ms lag to any user actions. A Service can accept multiple intents without stopping and starting again. Just handle each new intent in onStartCommand(). You don't need any complicated communication between the fragment and service; the fragment just needs to forward every request to the service and let the service do its thing. Although for a better UI you might need to bind to the service so it can update the UI based on the service's state.
Related
I have page with grid. I am loading data through service to grid. Loading and computing all data takes about 20-40 seconds. When I press button to get data, page start loading (classical in vaadin top loading indicator start loading).
My question is, how can I stop loading/waiting for data?
I can't stop searching process on that server I am getting data from, it dont have this functionality, I can only request for data, and wait for them.
Should I stop some thread? should i use something like this.getUI... and somewhere here stop it?
I am using vaadin 7.7.4
Thank you :)
You should use threads for this.
You will need to separate your logic, that the main thread does add all components to the UI.
This thread then also needs to spawn a new thread which does fetch the data and then updates the UI accordingly.
To update the UI once the data has been fetched from the backend you will need to activate push in your UI.
Don't forget to synchronise thread access to the UI with something like:
ui.access(new Runnable() {
#Override
public void run() {
...grid_update_with_new_data... ;
}
});
The fetching of the data should occur outside the ui.access method, otherwise your UI will freeze during backend data loading.
See this post for more technical details
Using Thread with Vaadin? and https://vaadin.com/docs/v7/framework/advanced/advanced-push.html
#André Schild This is simplified code. When I hit search button, app start searching, no problem with that. Problem is how to STOP searching, before its done. Enough for me is to stop waiting for response, and stop loading bar at top of the page, but I dont know how to achive this.
#SpringComponent
#UIScope
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DistraintSearchComponent extends CustomComponent {
#Autowired
private Service service
private Button searchButton = new Button("Search");
public void init(){
searchButton.addClickListener(new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
List<Results> results = service.findByFilter(filter);
refreshGrid(results);
}
});
}
}
my Activity shows to the user some data, which are download from a web server. Data could change over the time, so the web server communicates new updates to the connected clients.
So the work of my application is basically this:
while ( true ) {
wait for updates;
update the UI;
}
This code could run forever, and during its life it should update the UI many times.
What class should I use to implement this code?
Thread or Runnable seems the easiest solutions to my problem, but how could I comunicate to the UI thread?
onServerChangesListener... refresh UI
public void serverStateWrappr(){
Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
_localstr = getStuff((String) msg.obj)
updateAdapter(_localstr)
}}
from the thread which has a handleRef ...
while (onChangesForClient) {
Message msg = Message.obtain();
msg.what=1;
msg.obj=newData;
//TODO this is the comment for UI
mhandleRef.sendMessage(msg);
}
}
You should probably go with an asyncTask, calling runOnUiThread when you need to update the UI. Have a look to this question to see how activity.runOnUiThread() should be used
IMHO AsyncTask is preferrable, because it gives you more fine-grained control over your background task via onPreExecute(), onPostExecute()
I just wondering - where the JSONObject or JSONArray received from the web-server should be parsed in Android app - in the main UI or should be delivered to the another one ?
For example, I'm using Volley library :
private void fetchResults(){
RequestQueue queue = Volley.newRequestQueue(mContext);
String url = AuthenticationRequester.URL_GET_ALL_ORDERS;
JsonArrayRequest jsonDepartureObj = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
iVolleyCallback.onJSONArraySuccess(jsonArray);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
// hide the progress dialog
}
});
queue.add(jsonDepartureObj);
}
So should I put the iVolleyCallback.onJSONArraySuccess(jsonArray); in another thread execution or can be maintained the the main UI thread ?
Let's imagine that the incoming JSON is big and needs some time to be proceeded ?
The same question relates to the AsyncTask and to other possible ways working with the web-services in Android.
It is prefered that, every task that takes long time, should be proccessed in another thread to avoid overloading MainThread:
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
So if you know that you have big data and it will take time, you will use new thread, but if the data are small and takes less time, why take the risk? Move that to the new thread too
If, as you say yourself, the JSON data could be huge, and it could take some time to process, I think you could (or should?) try to process it in an AsyncTask. By doing this your UI thread will not be frozen during the processing.
In most GUI designs (not just Android), there are several threads having different roles and responsibilities:
The "main thread," running at "normal" dispatching priority, basically has nothing else to do but to respond promptly to the demands of the user-interface system. When "messages" arrive for its consumption, this thread immediately pre-empts the other threads so that the message can be processed quickly. Like any good manager ... ;-) ... they don't do the work themselves. They pass it off to other people.
When asynchronous requests (JSON ... etc.) are involved, there's usually a small "pool" of threads who are responsible for sending those to the host, receiving the response, doing the encoding/decoding, and then either acting-on the response or passing it along. These threads spend nearly all their time waiting on the host. They operate at a slightly-inferior dispatching priority.
Worker threads, operating at an even-more inferior priority, do any work that is computationally time-consuming. As much as possible, these threads don't do much I/O. They give-up their time slices quickly and readily to any other thread, but they usually consume their entire time slice when they can get one.
Potentially long running operations should always happen on a separate thread, or really any work (within reason...) that can be done on a separate thread should.
In your case, you're using Volley, so it's very easy for you to override your Request<T>'s parseNetworkResponse(NetworkResponse response); method, and parse the response on a background thread (since this method already runs on a background thread) before it's delivered. Since it's relatively seamless to do so, there really isn't a reason to not parse the response on a background thread.
Try this https://github.com/yakivmospan/volley-request-manager
//Queue using custom listener
RequestManager.queue()
.useBackgroundQueue()
.addRequest(new TestJsonRequest(), mRequestCallback)
.start();
private RequestCallback mRequestCallback = new RequestCallback<JSONObject, ResultType>() {
#Override
public ResultType doInBackground(JSONObject response) {
//parse and save response data
return new ResultType();
}
#Override
public void onPostExecute(ResultType result) {
//update UI here
Toast.makeText(getApplicationContext(), "Toast from UI", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(VolleyError error) {
//handle errors here (UI thread)
L.e(error.toString());
}
};
This question already has an answer here:
How to call asyncTasks periodically
(1 answer)
Closed 8 years ago.
Helly Community. I´m fairly new to Android and probably the biggest noob when it comes to networking and backend.
Right now I´m having following problem.
I´m building a simple chatting application and want my app to check the Parse server for a specific message parseobject.
Getting the Objects, working with them and deleting them works fine.
If i do it only once.
This is how I get messages from the Cloud and add them to my App Layout.
ParseQuery<ParseObject> query = ParseQuery.getQuery("message");
query.whereEqualTo("recipient", getRemote_id());
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> messages, ParseException e) {
if(messages != null){
Iterator itr = messages.iterator();
while(itr.hasNext()){
ParseObject message = (ParseObject)itr.next();
addMessageToLayout(message.getString("text"), "in", "new", "");
try {
message.delete();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
});
I want my app to check for new messages the whole time.
Ive tried with AsyncTask and a while(true) loop. The loop constantly creates new asynctask objects.
As result the app doesn´t react anymore and crashes.
When I use an instance of the runnable class im getting following error: NetworkOnMainThreadException, and the App crashes.
Because of this error i tried using asynctask in the first place. Isn´t a runnably object running on a different thread than the main thread as well?
I tried putting the thread to sleep for some seconds, still the app crashes in case of the async task.
Could the Problem be following: Im using anoher runnable object to update some animation in my app.
I also tried not using any kind of threading as the parse methods already work in background so they probably dont even need one. Again the app crashes because of an NetworkOnMainThreadException.
///_////
The weirdest thing comes now. If i´m not using a loop, and just check for messages when i enter the activity at first i´m getting an NetworkOnMainThreadException, but then the application somehow recovers into the newly opened activity and loads my messages from the server.
During that time of course the UI is blocked though. Still, thats the only way i can get it to work right now.
Doing it with a Handler and the TimerTask works, I can´t seem to close the thread when i exit the Activity though.
Here my code:
public void startLookingForMessages(){
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
new GetMessagesTask().execute();
}
});
}
};
timer.schedule(task, 0, 1000);
}
I found out that im getting the NetworkOnMainThreadException only if i´m trying to shut down the thread or close the while loop when calling onStop(). If I let the thread do its own thing, that means not putting in any code to stop it any time, my app works fine.
How could i overcome this problem?
I know this is getting kinda long. But maybe someone has the same Problem and can get some Info here.
Thanks you for your help already =)
Don't do it this way. Just don't.
Think about it: you're calling an AsyncTask to check periodically if something is there. Now, that gets to be quite expensive. Think about the battery and network resources you waste if that message is not there. Therefore, you waste a lot of resources. It's not a good idea to do it like this. You waste the user's resources. In addition, you also need a service to run in the background, as your app will not always be running.
A good way to solve this is to use Google Cloud Messaging. So what Google Cloud Messaging does is it "pings" a device every time there's an update. This makes life easier on you, as you only need to check if your app has received one of these pings, and it also saves battery and network resources.
If you're using PHP for your server-side application, you can use this to get started with GCM and PHP: GCM with PHP (Google Cloud Messaging)
This page on Google's website should also help with implementing it.
By using GCM, you'll also avoid having infinite loops or checking for more information every x minutes. You don't have to check yourself if new information is available; it'll ping you when it's available.
I need to implement a regular heartbeat.
The heartbeat itself is a simple HTTP-GET call to my server.
The thing is I want to send it as long as my app is open. When I close the app the sending should stop.
I read a few things about Services and AlarmManager but how can I call/stop them when navigating through my app activities?
This also seems nice but still the same problem:
final Handler handler = new Handler();
Runnable runable = new Runnable() {
#Override
public void run() {
try{
//do your code here
//also call the same runnable
handler.postDelayed(this, 1000);
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable
handler.postDelayed(this, 1000);
}
}
};
handler.postDelayed(runable, 1000);
Could anybody maybe post a good example or a link?
Thanks!
The thing is I want to send it as long as my app is open. When I close
the app the sending should stop
In android a bit harder than in iOS, but lets do it:
In Android you don't have a callback at application level when the app it goes to background or is killed. Instead of thins you should handle at each Activity onStop Method for example. Take a look at Activity lifecycle:
or onDestroy method. Note:
When an activity it isn't visible anymore it can be because your app is gone to background, closed or other activity is visible. You have to decide which case is and use your HTTP Get / Post, or stop it , when needed.
Here is a sample code with Async task to send data over HTTP.
I implemented a simple timeout using a similar Handler to your code. When an Activity calls onPause trigger the timeout on a 10 second delay, when an Activity calls onResume cancel that call with removeRunnable(...) if the timeout code fires you know the user has left your app (this is the reason for the 10 second timeout, to give a new Activity time to launch if there is one).
You could add something in your timeout code to kill the heartbeat. e.g. cancel the heartbeat Runnable