Je veux que du code s'exécute en arrière-plan en permanence. Je ne veux pas le faire dans un service. Y a-t-il un autre moyen possible?
J'ai essayé d'appeler la classe Thread
dans mon Activity
, mais ma Activity
reste en arrière-plan pendant un moment puis s'arrête. La classe Thread
cesse également de fonctionner.
class testThread implements Runnable {
@Override
public void run() {
File file = new File( Environment.getExternalStorageDirectory(), "/BPCLTracker/gpsdata.txt" );
int i = 0;
RandomAccessFile in = null;
try {
in = new RandomAccessFile( file, "rw" );
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String line =null;
while ( true ) {
HttpEntity entity = null;
try {
if ( isInternetOn() ) {
while ( ( line = in.readLine() ) != null ) {
HttpClient client = new DefaultHttpClient();
String url = "some url";
HttpPost request = new HttpPost( url );
StringEntity se = new StringEntity( line );
se.setContentEncoding( "UTF-8" );
se.setContentEncoding( new BasicHeader( HTTP.CONTENT_TYPE, "application/json" ) );
entity = se;
request.setEntity( entity );
HttpResponse response = client.execute( request );
entity = response.getEntity();
i++;
}
if ( ( line = in.readLine() ) == null && entity != null ) {
file.delete();
testThread t = new testThread();
Thread t1 = new Thread( t );
t1.start();
}
} else {
Thread.sleep( 60000 );
} // end of else
} catch (NullPointerException e1) {
e1.printStackTrace();
} catch (InterruptedException e2) {
e2.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}// end of while
}// end of run
}
Si tu as besoin de:
exécuter du code sur un thread d'arrière-plan
exécuter du code qui ne touche pas/met à jour l'interface utilisateur
exécuter (code court) ce qui prendra au plus quelques secondes
ALORS utilisez le modèle propre et efficace suivant, qui utilise AsyncTask:
AsyncTask.execute(new Runnable() {
@Override
public void run() {
//TODO your background code
}
});
N'oubliez pas que l'exécution en arrière-plan, l'exécution en continu sont deux tâches différentes.
Pour les processus d'arrière-plan à long terme, les threads ne sont pas optimaux avec Android. Cependant, voici le code et faites-le à vos risques et périls ...
Rappelez-vous que Service ou Thread fonctionnera en arrière-plan, mais notre tâche doit déclencher (appeler encore et encore) pour obtenir les mises à jour. En d'autres termes, une fois la tâche terminée, nous devons rappeler la fonction pour la prochaine mise à jour.
Timer (déclenchement périodique), Alarm (déclenchement de la base de temps), Broadcast (déclenchement de base d'événements), la récursivité réveillera nos fonctions.
public static boolean isRecursionEnable = true;
void runInBackground() {
if (!isRecursionEnable)
// Handle not to start multiple parallel threads
return;
// isRecursionEnable = false; when u want to stop
// on exception on thread make it true again
new Thread(new Runnable() {
@Override
public void run() {
// DO your work here
// get the data
if (activity_is_not_in_background) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// update UI
runInBackground();
}
});
} else {
runInBackground();
}
}
}).start();
}
tilisation du service: Si vous lancez un service, celui-ci démarrera, il exécutera la tâche et se terminera. après l'exécution de la tâche. résilié peut également être dû à une exception, ou l’utilisateur l’a supprimé manuellement des paramètres. START_STICKY (Sticky Service) est l'option proposée par Android. Ce service redémarre automatiquement si le service est interrompu.
Rappelez-vous la question différence entre le multitraitement et le multithreading? Le service est un processus en arrière-plan (tout comme une activité sans interface utilisateur), de la même manière dont vous lancez un thread dans l'activité pour éviter la charge sur le thread principal (Activity thread) , de la même manière que vous devez lancer des threads (ou des tâches asynchrones) sur le service pour éviter la charge sur le service.
Dans une seule instruction, si vous souhaitez exécuter une tâche d’arrière-plan continue, vous devez lancer StickyService et exécuter le fil dans le service de la base d’événements.
Je veux que du code s'exécute en arrière-plan en permanence. Je ne veux pas le faire dans un service. Y a-t-il un autre moyen possible?
Le mécanizm probable que vous recherchez est AsyncTask
. Il est directement désigné pour effectuer un processus d'arrière-plan sur un thread en arrière-plan. En outre, son principal avantage est qu'il offre quelques méthodes qui s'exécutent sur le fil principal (UI) et permettent de mettre à jour votre interface utilisateur si vous souhaitez annoncer à l'utilisateur des progrès dans la tâche ou mettre à jour l'interface utilisateur avec des données extraites du processus en arrière-plan.
Si vous ne savez pas comment commencer, voici le didacticiel de Nice:
Remarque: Il est également possible d'utiliser IntentService
avec ResultReceiver
, qui fonctionne également.
Robospice est une alternative à AsyncTask. https://github.com/octo-online/robospice .
Certaines des fonctionnalités de robospice.
1.exécute les requêtes réseau de manière asynchrone (dans un arrière-plan AndroidService) (par exemple: REST à l'aide de Spring Android). Notifiez votre application, sur le fil de l'interface utilisateur, lorsque le résultat est prêt.
2.est fortement typé! Vous faites vos demandes en utilisant des POJO et vous obtenez des POJO en tant que résultats de demande.
3. N'imposez aucune contrainte sur les POJO utilisés pour les demandes ni sur les classes d'activité que vous utilisez dans vos projets.
4.caches résultats (dans Json avec Jackson et Gson, ou XML, ou des fichiers texte à plat, ou des fichiers binaires, même en utilisant ORM Lite).
5.notifie vos activités (ou tout autre contexte) du résultat de la requête réseau si et seulement si elles sont toujours vivantes
6.Aucune fuite de mémoire, comme Android Loaders, contrairement à Android AsyncTasks notifie vos activités sur leur thread d'interface utilisateur.
7. utilise un modèle de gestion des exceptions simple mais robuste.
Des échantillons pour commencer. https://github.com/octo-online/RoboSpice-samples .
Un exemple de robospice sur https://play.google.com/store/apps/details?id=com.octo.Android.robospice.motivations&feature=search_result .
class Background implements Runnable {
private CountDownLatch latch = new CountDownLatch(1);
private Handler handler;
Background() {
Thread thread = new Thread(this);
thread.start();
try {
latch.await();
} catch (InterruptedException e) {
/// e.printStackTrace();
}
}
@Override
public void run() {
Looper.prepare();
handler = new Handler();
latch.countDown();
Looper.loop();
}
public Handler getHandler() {
return handler;
}
}
Si vous avez besoin d'exécuter des threads avec des codes différents, voici un exemple:
Auditeur:
public interface ESLThreadListener {
public List onBackground();
public void onPostExecute(List list);
}
Classe de fil
public class ESLThread extends AsyncTask<Void, Void, List> {
private ESLThreadListener mListener;
public ESLThread() {
if(mListener != null){
mListener.onBackground();
}
}
@Override
protected List doInBackground(Void... params) {
if(mListener != null){
List list = mListener.onBackground();
return list;
}
return null;
}
@Override
protected void onPostExecute(List t) {
if(mListener != null){
if ( t != null) {
mListener.onPostExecute(t);
}
}
}
public void setListener(ESLThreadListener mListener){
this.mListener = mListener;
}
}
Exécuter différents codes:
ESLThread thread = new ESLThread();
thread.setListener(new ESLThreadListener() {
@Override
public List onBackground() {
List<EntityShoppingListItems> data = RoomDB.getDatabase(context).sliDAO().getSL(fId);
return data;
}
@Override
public void onPostExecute(List t) {
List<EntityShoppingListItems> data = (List<EntityShoppingListItems>)t;
adapter.setList(data);
}
});
thread.execute();