Android и длительное фоновое задание - PullRequest
0 голосов
/ 09 января 2019

У меня есть приложение Xamarin для Android. Мне нужно запустить долгосрочную задачу в этом приложении. Как я знаю, я должен использовать класс Service для него. Я создал такой класс:

[Service]
public class BackgroundService : IntentService
{
    Handler mHandler;

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        mHandler = new Handler();
        SomeTask();
        return 0;
    }

    private void SomeTask()
    {
        // Thread.CurrentThread.ManagedThreadId here is 1
        Thread.Sleep(5000);
        for (int i = 1; i <= 10; i++)
        {
            mHandler.Post(new Runnable(() =>
            {
                Toast.MakeText(this, $"Current thread ID in service: {Thread.CurrentThread.ManagedThreadId}", ToastLength.Short).Show();
            }));
        }
        StopSelf();                       
    }

    protected override void OnHandleIntent(Intent intent)
    {
    }
}

А как я использую сервис в действии:

// And here Thread.CurrentThread.ManagedThreadId is 1
var serviceToStart = new Intent(this, typeof(BackgroundService));
StartService(serviceToStart);

Я ожидал, что эта служба запускается в другом фоновом потоке, но Thread.CurrentThread.ManagedThreadId по активности точно такой же, как Thread.CurrentThread.ManagedThreadId в методе SomeTask класса BackgroundService. Более того, когда SomeTask работает, мое приложение не отвечает. Очевидно, это означает, что сервис не работает в фоновом потоке. Как сделать так, чтобы служба работала в фоновом потоке / процессе?

1 Ответ

0 голосов
/ 10 января 2019

Вы должны открыть Toast в методе OnHandleIntent и изменить код с new Handler() на new Handler(Looper.MainLooper).

Вы можете обратиться к следующей демонстрации.

enter image description here

IntentServiceDemo.cs

[Service]
public  class IntentServiceDemo : IntentService
{

    Handler mHandler;
    public IntentServiceDemo() : base("IntentServiceDemo")
    {

    }
    protected override void OnHandleIntent(Intent intent)
    {
        mHandler = new Handler(Looper.MainLooper);
        SomeTask();
    }

    private void SomeTask()
    {
        Thread.Sleep(1000);
        int id=System.Threading.Thread.CurrentThread.ManagedThreadId;
        for (int i = 1; i <= 10; i++)
        {
            mHandler.Post(new Runnable(() =>
            {

                Toast.MakeText(ApplicationContext, $"Current thread ID in service:"+ id, ToastLength.Short).Show();

            }));
        }
        StopSelf();
    }
}

MainActivity.cs

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
    //string TAG = "DemoService:";
  //  private Messenger messenger; // Instance variable for the Messenger
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.activity_main);
        int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
        Toast.MakeText(this ,"Main thread"+ id, ToastLength.Short).Show();
        Button bt_service = FindViewById<Button>(Resource.Id.bt_service);

        bt_service.Click += (e, o) =>
        {
            Intent downloadIntent = new Intent(this, typeof(IntentServiceDemo));
            StartService(downloadIntent);

        };

    }

activity_main.axml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 <Button
  android:id="@+id/bt_service"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="startService"/>
</RelativeLayout>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...