open c# xamarin xamarin.forms

c# - open - webview xamarin ios



¿Cómo puedo ejecutar un método en segundo plano en mi aplicación Xamarin? (7)

Una vez que la aplicación esté abierta y ejecutándose, me gustaría un proceso en segundo plano para verificar una base de datos y hacer una actualización dependiendo de los datos en la base de datos. Me gustaría hacer esta comprobación cada minuto. Solo quiero que esto suceda cuando la aplicación está en primer plano y a la vista del usuario.

¿Puede alguien darme algunas sugerencias sobre cómo hago esto? Supongo que puedo llamar a un método desde aquí, pero no estoy seguro de cómo hacer esto. Además, no sé cómo parar o incluso si necesito cancelar / detener el proceso manualmente. ¿Se cancelará solo cuando la aplicación no esté en primer plano y se reiniciará cuando la aplicación vuelva a estar en primer plano?

public partial class App : Application { protected override void OnStart() { App.DB.InitData(); MainPage = new Japanese.MainPage(); }

Pero, ¿necesito hacer que esto se ejecute en un hilo diferente? Si es así, ¿cómo podría hacer eso?

Lo siento si mi pregunta no está clara. Por favor pregunte y puedo actualizar si no tiene sentido.


Estoy haciendo algo como esta es mi aplicación Xamarin Forms.

public void execute() { var thread = new Thread(new ThreadStart(startAuthenticationProcess)) { IsBackground = true }; thread.Start(); } private void startAuthenticationProcess() { Thread.Sleep(2000); if (!Utils.isNetworkAvailable(splashActivity)) { splashActivity.RunOnUiThread(() => Utils.showToast(splashActivity, splashActivity.GetString(Resource.String.r30025))); splashActivity.FinishAffinity(); } else { try { if (StringUtils.isBlank(strIPAdd) || (StringUtils.isNotBlank(strIPAdd) && (StringUtils.isBlank(strDbName) || "site".Equals(strDbName,StringComparison.OrdinalIgnoreCase)))) { splashActivity.RunOnUiThread(() => DependencyService.Get<IAuthenticationDialog>().showAuthenticationDialog(new Command(() => { var intent = new Intent(splashActivity, typeof(MainActivity)); intent.PutExtra("startLoginActivity", false); splashActivity.StartActivity(intent); splashActivity.Finish(); }))); } else { gotoLoginScreen(); } } catch (Exception e) { Log.Error(TAG, e.Message); } } }


Fácil, pruebe algo como esto e implemente su lógica en esos métodos:

public partial class App : Application { protected override void OnStart() { // Your App On start code should be here... // and then: Task.Run(() => { //Add your code here, it might looks like: CheckDatabase(); MakeAnUpdateDependingOnDatabase(); }); }

Espero que ayude.


Hay algunas formas de hacerlo en iOS y Android. En Xamarin Forms, la mayor parte de esta funcionalidad cae bajo el nombre de Backgrounding . Hay muchos tutoriales por ahí. Este es bastante elaborado y definitivamente vale la pena echarle un vistazo:

http://arteksoftware.com/backgrounding-with-xamarin-forms/

En Android, gran parte de este trabajo se realiza en un servicio en segundo plano . Para iOS, mire las tareas de ejecución larga o de longitud definida . Como se puede ver a partir de esto, no hay forma de hacer las formas Xamarin. Deberá escribir el código específico de Xamarin.Android y Xamarin.iOS.


Lo que hicimos en nuestra aplicación de formularios fue hacer uso del dispositivo. Temporizador y la clase cronómetro disponibles en System.Diagnostics, y Xamarin.Forms para crear un temporizador administrado muy genérico con el que pudiéramos interactuar usando onStart, onSleep y onResume. métodos en Xamarin.Forms.

Esta solución particular no requiere ninguna lógica especial específica de la plataforma, y ​​el temporizador y el cronómetro del dispositivo no bloquean la UI.

using Xamarin.Forms; using System; using System.Linq; using System.Diagnostics; namespace YourNamespace { public partial class App : Application { private static Stopwatch stopWatch = new Stopwatch(); private const int defaultTimespan = 1; protected override void OnStart() { // On start runs when your application launches from a closed state, if (!StopWatch.IsRunning) { StopWatch.Start(); } Device.StartTimer(new TimeSpan(0, 0, 1), () => { // Logic for logging out if the device is inactive for a period of time. if (StopWatch.IsRunning && StopWatch.Elapsed.Minutes >= defaultTimespan) { //prepare to perform your data pull here as we have hit the 1 minute mark // Perform your long running operations here. InvokeOnMainThread(()=>{ // If you need to do anything with your UI, you need to wrap it in this. }); stopwatch.Restart(); } // Always return true as to keep our device timer running. return true; }); } protected override void OnSleep() { // Ensure our stopwatch is reset so the elapsed time is 0. StopWatch.Reset(); } protected override void OnResume() { // App enters the foreground so start our stopwatch again. StopWatch.Start(); } } }


Editar:

Para dar un contexto sobre cómo funciona la solución anterior paso a paso:

La aplicación comienza desde un estado cerrado y el método ''OnStart ()'' crea nuestro dispositivo. El temporizador marca cada segundo. También inicia nuestro cronómetro que cuenta hasta un minuto.

Cuando la aplicación pasa a segundo plano, se aplica el método ''OnSleep'' en este punto si tuviéramos que pasar un valor ''falso'' en nuestra acción Device.StartTimer () no se iniciará de nuevo. Así que, en su lugar, simplemente reiniciamos nuestro cronómetro para cuando la aplicación se abra nuevamente.

Cuando la aplicación vuelve al primer plano, aparece el método ''OnResume'', que simplemente inicia el cronómetro existente.

2018 Editar:

Esta respuesta todavía tiene algunos méritos, incluso en 2018, pero principalmente para situaciones muy específicas. Hay mejores formas específicas de plataforma para replicar esta funcionalidad incluso en Xamarin.Forms. Lo anterior sigue siendo una forma independiente de la plataforma para realizar una tarea después de un período de tiempo, teniendo en cuenta la actividad / inactividad del usuario.


Para ejecutar una tarea en segundo plano usa un servicio . Generalmente clasifica las tareas como tareas de ejecución larga o tareas periódicas.

El código para el servicio en Android se parece a esto

[Service] public class PeriodicService : Service { public override IBinder OnBind(Intent intent) { return null; } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { // From shared code or in your PCL return StartCommandResult.NotSticky; } }

E invocar el servicio en segundo plano

var intent = new Intent (this, typeof(PeriodicService)); StartService(intent);

En caso de que quiera invocar y verificar después de cada minuto

private void StartBackgroundDataRefreshService () { var pt = new PeriodicTask.Builder () .SetPeriod (1800) // in seconds; minimum is 30 seconds .SetService (Java.Lang.Class.FromType (typeof(BackgroundService))) .SetRequiredNetwork (0) .SetTag (your package name) // package name .Build (); GcmNetworkManager.GetInstance (this).Schedule (pt); }

Para saber qué tipo de servicio es bueno para ti, lee este tutorial Tipos de servicios

Blog de Xamarin para el servicio de fondo periódico Xamarin Service Blog

El otro ejemplo es

public class PeriodicService : Service { private static Timer timer = new Timer(); public override IBinder OnBind(Intent intent) { return null; } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { timer.scheduleAtFixedRate(new mainTask(), 0, 5000); return StartCommandResult.NotSticky; } private class mainTask extends TimerTask { public void run() { //your code } } }

Aquí está el código de ejemplo del servicio Android XAMARIN que realizará la tarea después de cada 10 segundos

using System; using System.Threading; using Android.App; using Android.Content; using Android.OS; using Android.Util; namespace SimpleService { [Service] public class SimpleStartedService : Service { static readonly string TAG = "X:" + typeof(SimpleStartedService).Name; static readonly int TimerWait = 10000; Timer timer; DateTime startTime; bool isStarted = false; public override void OnCreate() { base.OnCreate(); } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { Log.Debug(TAG, $"OnStartCommand called at {startTime}, flags={flags}, startid={startId}"); if (isStarted) { TimeSpan runtime = DateTime.UtcNow.Subtract(startTime); Log.Debug(TAG, $"This service was already started, it''s been running for {runtime:c}."); } else { startTime = DateTime.UtcNow; Log.Debug(TAG, $"Starting the service, at {startTime}."); timer = new Timer(HandleTimerCallback, startTime, 0, TimerWait); isStarted = true; } return StartCommandResult.NotSticky; } public override IBinder OnBind(Intent intent) { // This is a started service, not a bound service, so we just return null. return null; } public override void OnDestroy() { timer.Dispose(); timer = null; isStarted = false; TimeSpan runtime = DateTime.UtcNow.Subtract(startTime); Log.Debug(TAG, $"Simple Service destroyed at {DateTime.UtcNow} after running for {runtime:c}."); base.OnDestroy(); } void HandleTimerCallback(object state) { TimeSpan runTime = DateTime.UtcNow.Subtract(startTime); Log.Debug(TAG, $"This service has been running for {runTime:c} (since ${state})." ); } }

}


Puedes usar

Device.StartTimer(TimeSpan.FromMinutes(1), () => { var shouldTimerContinueWork = true; /*your code*/ return shouldTimerContinueWork; });

Este temporizador se ejecuta en el hilo de fondo, utiliza el reloj de los dispositivos y la reentrada segura.
Para detener este temporizador cuando la aplicación está en segundo plano, puede usar los métodos Xamarin.Forms.Application OnSleep y OnResume como se describe here


puedes usar esto,

System.Threading.Tasks.Task.Run(() => { //Add your code here. }).ConfigureAwait(false);