2015-09-10 5 views
0

Я встречаюсь с проблемой, чтобы понять, что является лучшим решением для того, что я хочу делать. (И у меня проблемы с пониманием того, как они работают точно)Android: IntentService или обработчик

Часто я использую Asynctask, но в этом случае я думаю, что это не то, что мне нужно.

В действии (A) Я хочу запустить задачу, которая отправляет данные в WS, и это может занять 10-20 секунд. Я хочу разрешить пользователю делать что-то еще в приложении за это время.

Когда эта задача выполнена, я хочу вызвать другое действие, но если есть ошибки, я хочу показать их в тосте. Я тоже хочу показать индикатор прогресса, если пользователь находится в этом действии (A).

Таким образом, я вижу, что IntentService может мне помочь, потому что он не «связан» с активностью, он работает в фоновом режиме и т. Д., Но, похоже, немного сложно связать с потоком пользовательского интерфейса. (в моем случае, если есть проблема, я хочу что-то сделать в своей деятельности A).

Другая часть, обработчик может использоваться, но если действие уничтожено, поток работает всегда, но как я могу «восстановить» ссылку с активностью, если пользователи возвращаются к активности (A)? (со статическим классом, чтобы сохранить его?).

Так что если у вас есть какие-либо ссылки/посоветуйте/другие, чтобы дать мне больше объяснений, я буду признателен :) (я в доке прочитанных Android.)

ответ

2

Сначала используйте IntentService - они предназначены для точно такого рода вещи. Вторая часть вашего вопроса занимает немного больше времени, чтобы ответить, но неся со мной ;-)

По сути, одна из двух вещей может случиться, пока ваш IntentService занят разговором с сервером: 1) пользователь переходит от вашего, 2) пользователь остается в вашем приложении. Вы можете ответить на это, выполнив следующие действия:

  1. Ваш IntentService должен отправить заказную трансляцию, когда она завершится, с информацией о том, была ли она успешной.
  2. Для действий, которые вы хотите отреагировать на эту трансляцию, создайте для них базовую реализацию, которая регистрирует вещательный приемник в onResume() и избавится от него в onPause(). Они должны отменить трансляцию, если они отреагируют на нее.
  3. Создайте второй (но автономный) широковещательный приемник для своей трансляции и зарегистрируйте его в манифесте с приоритетом 0, поэтому он всегда будет последним, кто узнает о вашем завершении IntentService , Этот ресивер отвечает за создание уведомлений для пользователя, который щелкнет, что приведет их в соответствующее место в вашем приложении.

Вот скелетный манифест:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="bubblebearapps.co.uk.blah" > 

<permission android:name="change_this_name" 
    android:label="my_permission" 
    android:protectionLevel="dangerous"/> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 

    <uses-permission android:name="change_this_name"/> 

    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <receiver 
     android:name=".MyReceiver" 

     android:enabled="true" 
     android:exported="false" 
     android:permission="change_this_name"> 
     <intent-filter android:priority="0"> 
      <action android:name="action_name_here"/> 

     </intent-filter> 
    </receiver> 
</application> 

</manifest> 

Barebones активность:

public class MainActivity extends AppCompatActivity { 

public static final String YOUR_ACTION = "this_action_matches_the_one_in_the_manifest"; 
public static final String YOUR_PERMISSION = "this_permission_matches_the_one_in_the_manifest"; 


private InterceptsReciever mReceiver; 

private void doSomethingWithBroadcast(Intent intent) { 
    // this method must return quickly! If you've got something long to do, do it on a background thread 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    mReceiver = new InterceptsReciever(this); 
} 

@Override 
protected void onPause() { 
    unregisterReceiver(mReceiver); 
    super.onPause(); 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

public static class InterceptsReciever extends BroadcastReceiver { 


    private final MainActivity mainActivity; 

    public InterceptsReciever(MainActivity mainActivity) { 
     this.mainActivity = mainActivity; 
     IntentFilter filter = new IntentFilter(YOUR_ACTION); 
     filter.setPriority(1); //anything above the manifest. You could have higher priorities for nested fragments or whatever if you like.... 

     mainActivity.registerReceiver(this, 
       filter, 
       YOUR_PERMISSION, 
       null); 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 

     if (YOUR_ACTION.equals(intent.getAction())) { 

      mainActivity.doSomethingWithBroadcast(intent); 
      abortBroadcast(); // this prevents other the manifest broadcast being called 

     } 

    } 
} 


/** 
* Example of how to send broadcasts 
* @param context 
*/ 
public static void sendBroadcast(Context context){ 

    Intent intent = new Intent(YOUR_ACTION); 

    context.sendOrderedBroadcast(
      intent, 
      YOUR_PERMISSION  // this protects your broadcast from being seen by just anyone 
    ); 

} 



} 
+0

Thx за вашу помощь :) Первый вопрос, почему IntentService лучше, чем обработчик для этого случая? Потому что кажется, может быть, легче что-то сделать с обработчиком? – deveLost

+0

IntentService имеет немного больше шаблонов, я признаю, но у него есть свой жизненный цикл и контекст, поэтому он менее подвержен ошибкам. Также главное преимущество IntentSevice заключается в том, что вы можете увольнять столько, сколько пожелаете ваше сердце, но оно будет работать только по одному! Это означает, что вам даже не нужно беспокоиться о том, сколько потоков у вас открыто и т. Д. – JoeyJubb

+0

Хорошо, я понимаю!Я собираюсь попробовать это, посмотрю, я вернусь, если у меня возникнут проблемы: D – deveLost

Смежные вопросы