I've a Service that is called from an Activity with this code:
startService(new Intent(AMC_Activity.this,CallService.class));
Service is running good for about 20-30 minutes, but after that service stop running, I know that I can use 'foreground' service, but by using that I should show a notification, so, is there any other way to prevent service stop running?
I am not sure but i think you are starting your service from UI thread and after that you are putting your in application background so after sometime your activity instance getting lost and that UI thread also killed at that time.
Solution
Create a new Thread and start service with that Thread instead of UI Thread, because service is doing work on that Thread whoever Thread is invoking it.
//This code will be in class body.
private Thread thread1 = new Thread(){
public void run(){
startService(new Intent(AMC_Activity.this,CallService.class));
}
}
//Now this code will be call when you are going to start the service, i.e. Under onCreate()
thread1.start();
It may helpful to you.
If you use a TaskManager App on your device you should take care that it doesn't kill your app and/or service too.
Related
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.
I have an Android app with three threads, the main thread and two worker threads. The threads need to communicate with each other regularly.
I had originally gone about doing this in a horrible way that everyone here would yell at me for. I saved instances of the thread in each thread and called methods of the class from the other threads if a thread needed that functionality. It worked, but I knew it wasn't right.
Since that was wrong, I went back through and changed each instance of a thread to an instance of the thread's handler, and each thread function call I replaced with a handler.sendMessage call.
Now the program doesn't work. It just freezes, and I have no idea whats going on. When using the debug perspective, I step through the main thread but all I get is the function
boolean hasMessages(Handler h, int what, Object object)
{
...
}
from the MessageQueue. The other threads are looping in their run() function which doesn't do anything exciting. None of my logs are printing. I am at a loss for what is happening and I don't know what steps I should take next to continue debugging it. All I changed was adding handlers and sending messages. Can you guys suggest any next steps I should take for debugging?
Edit: Here is some code, I'm having no luck
Main Activity:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectionStatusTextView = (TextView) findViewById(R.id.connectionStatus);
imageView = (ImageView) findViewById(R.id.imageView);
commandView = (TextView)findViewById(R.id.commandView);
focusView = (TextView)findViewById(R.id.focusView);
mApplication = ((myApplication) this.getApplication());
ConnectedThread connectedThread = new ConnectedThread(mHandler, mApplication);
VoiceRecognitionThread voiceThread = new VoiceRecognitionThread(mApplication, this);
connectedThread.setHandlers(mHandler, voiceThread.getHandler());
voiceThread.setHandlers(mHandler, connectedThread.getHandler());
connectedThread.start();
voiceThread.start();
}
ConnectedThread and VoiceRecognitionThread both extend HandlerThread. They both create a class level Handler which handles messages sent to those threads. getHandler returns a reference to those handlers.
Just use a HandlerThread and feed it with messages via its handler object:
HandlerThread thread1 = new HandlerThread("Thread Name");
thread1.start();
handler1 = new MyHandler(thread1.getLooper());
// pass message for thread 1
handler1.sendmessage()
// and same for threads 2 and 3
Note that if you plan your threads to be long running, a far better
solution would be to use an IntentService.
IntentService are services and, as such, are by far less susceptible to
Android reclamation then resources gets low.
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
I want to port my client from Java Swing(Java client) to Android(Android client).
Basically, my Java client have a thread, which run a forever while loop to receive UDP packets, and base on content of UDP packets, UI of the corresponding JFrame will be updated.
Now I want my Android client has a background worker like the thread in the Java client, and that worker will be initialized in the main activity. Then when there are some requests from the UDP socket, the main activity will start some corresponding activities (Chat Activities), then there are some other requests come from the UDP socket, the worker will update on the activity(this activity can be main activity or a Chat Activity) which is being displayed on the screen.
So my question is what the background worker should be:
Service
Normal Java thread
Asynctask
or what...
Which is the most appropriate with my requirements?
Thanks!
The background worker should be a service, because
A Service is an application component that can perform long-running
operations in the background and does not provide a user interface.
while your UI will be a activity, your service will read the UDP packets and the activity will be modified accordingly.
A Service is the most suitable candidate in your case.
There is a class Application class for each android application . First extend it and it will be initialized on very first time your app will start even before your Activity . Initialize/ start your normal java thread to perfrom background work here . The key advantage will be you can get instance of this application class anywhere from the app (It means you can control on the background thread from anywhere in the applicaion . Send background http request etc.. whatever ....) .Then initialize the handler on the UI thread of particular activity upon which you want to do changes and do something like this.
private Handler myHandler ;
public void checkBackgroundAndUpdateUi()
{
if(conetxt.getApplicationContext().getStatus == completed)
{
initializeHandler();
handler.postRunnable(myRunnable);
}
}
Runnable myRunnable = new Runnable(){
public void run()
{
// update your UI views here .....
}
};
private void initializeHandler(){
myHandler = new Handler ();
}
I use FTP raw commands to upload file to a FTP server, I start a new thread to send file via socket in my code. when the newly started thread finished sending file I want to output some message to console, how can I make sure the thread have finished it's work ?
here is my code:
TinyFTPClient ftp = new TinyFTPClient(host, port, user, pswd);
ftp.execute("TYPE A");
String pasvReturn = ftp.execute("PASV");
String pasvHost = TinyFTPClient.parseAddress(pasvReturn);
int pasvPort = TinyFTPClient.parsePort(pasvReturn);
new Thread(new FTPFileSender(pasvHost, pasvPort, fileToSend)).start();
how can I make sure the thread have finished it's work ?
You do call Thread.join() like this:
...
Thread t = new Thread(new FTPFileSender(pasvHost, pasvPort, fileToSend));
t.start();
// wait for t to finish
t.join();
Note however that Thread.join will block until the other thread has finished.
A better idea is perhaps to encapsulate the upload-thread in a UploadThread class which performs some callback when it's done. It could for instance implement an addUploadListener and notify all such listeners when the upload is complete. The main thread would then do something like this:
UploadThread ut = new UploadThread(...);
ut.addUploadListener(new UploadListener() {
public void uploadComplete() {
System.out.println("Upload completed.");
}
});
ut.start();
For what you are trying to do, I see at least three ways to accomplish:
you could just let the uploading thread itself print the logging message or
in some other thread, you can join the upload thread. Using this approach you could do some other work before calling join, otherwise there is no gain from doing it in a separate thread.
you can implement some kind of listener, so an uploading Thread informs all registered listeners about it's progress. This is the most flexible solution, but also the most complex.