0

Я пытаюсь понять, как этот материал работает немного лучше.Является ли LocalBroadcastReceiver + IntentService правильной практикой?

Итак, я узнал о Runnables и Threads и ASyncTasks, но, видимо, у них есть некоторые серьезные недостатки, связанные с изменениями конфигурации, такими как вращение экрана.

Лучше ли использовать IntentService для чего-либо, что должно выполняться в фоновом режиме, например команды базы данных SQL, процедуры файловой системы, процессы ввода/вывода в Интернете и т. Д., А затем использовать LocalBroadcastReceiver для передачи результатов обратно в Activity?

+0

Конечно, пример поможет – user7025005

ответ

0

Что лучше использовать вместо IntentService для чего-нибудь, что должно выполняться в фоновом режиме, как команды баз данных SQL, процедуры файловой системы, ввод данные Интернета/выходных процессы и т.д. - и затем использовать LocalBroadcastReceiver передать результаты обратно к Мероприятия?

Служба, если ваш пользовательский интерфейс может перемещаться в фоновом режиме во время работы, и вы обеспокоены тем, что ваш процесс может быть прерван во время работы. Я обычно беспокоюсь только об этом, если работа может превысить секунду или около того. В противном случае достаточно простого потока.

Использование шины событий, например LocalBroadcastManager, является разумным подходом, позволяющим другим компонентам знать, когда ваш сервис/поток выполняется с его работой. This sample app демонстрирует это. Лично я склонен использовать EventBus greenrobot. — this sample app - это клон первого, но с использованием EventBus вместо LocalBroadcastManager.

+0

Но что мешает кому-то из поворота телефона в середине процесса резьбы? – user7025005

+0

@ user7025005: Ничего. Но нить не волнует. Вы используете шину событий, чтобы заинтересованные стороны знали об изменениях состояния. Такая сторона будет регистрироваться на шине событий для обновлений (например, вызывать 'registerReceiver()' на 'LocalBroadcastManager'), а затем делать что-то, чтобы получить текущее состояние (например, проверить диспетчер кеширования singleton). – CommonsWare

0

Следуйте примеру чата, используя одно действие (активность чата), в котором выполняется класс в службе (класс реального времени). Я использую mvc webapi для управления чатом между чатами. Когда в реальном времени получают сообщение «onConnected» или «ReceivedMessageServer», автоматически отправляет LocalBroadcastManager для активности чата. Таким образом, в onReceive от BroadcastReceiver получает сообщение и выполняет другие задачи.

а) ChatActivity.class

package br.com.yourapp; 
import android.app.ProgressDialog; 
import android.content.BroadcastReceiver; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.ServiceConnection; 
import android.content.res.Configuration; 
import android.media.MediaPlayer; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.app.AlertDialog; 
import android.support.v7.app.AppCompatActivity; 
import android.text.Editable; 
import android.text.TextWatcher; 
import android.util.Log; 
import android.util.TypedValue; 
import android.view.KeyEvent; 
import android.view.MenuItem; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.WindowManager; 
import android.view.inputmethod.InputMethodManager; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ListView; 
import android.widget.TextView; 
import java.util.Calendar; 
import br.com.yourapp.model.MessageReceived; 
import util.RealTime; 

public class ChatActivity extends AppCompatActivity implements View.OnClickListener, 
View.OnKeyListener , TextWatcher { 
    AppController obj; 
    private ProgressDialog pDialog; 
    MediaPlayer mp; 
    private ListView lstChatLog; 
    private ArrayAdapter<String> listAdapter; 
    private EditText txtChatMessage; 
    private TextView lblTyping; 
    private Button btnSendChat; 
    private boolean resultRequest = true; 
    private String errorMessage = "Internet is not working"; 
    private AlertDialog alertDialog; 
    private AlertDialog.Builder alertBuilder; 
    String userType = "V"; 
    String spaces = "\u0020\u0020\u0020\u0020"; 
    Calendar time; 
    MessageReceived msg; 
    private RealTime realTime; 
    private final Context mContext = this; 
    private boolean mBound = false; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_chat); 
     pDialog = new ProgressDialog(this); 
     pDialog.setMessage("Loading..."); 
     pDialog.setCancelable(false); 
     showProgressDialog(); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     obj = (AppController) getApplicationContext(); 
     getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 
     lblTyping = (TextView) findViewById(R.id.lblTyping); 
     txtChatMessage = (EditText) findViewById(R.id.txtChatMessage); 
     txtChatMessage.setOnKeyListener(this); 
     txtChatMessage.addTextChangedListener(this); 
     btnSendChat = (Button) findViewById(R.id.btnSendChat); 
     btnSendChat.setOnClickListener(this); 
     alertDialog = new AlertDialog.Builder(this).create(); 
     alertDialog.setTitle("Alert"); 
     alertBuilder = new AlertDialog.Builder(this); 
     lstChatLog = (ListView) findViewById(R.id.lstChatLog); 
     listAdapter = new ArrayAdapter<String>(ChatActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1) { 
      @Override 
      public View getView(int position, View convertView, ViewGroup parent) { 
       View view = super.getView(position, convertView, parent); 
       TextView tv = (TextView) view.findViewById(android.R.id.text1); 
       tv.setHeight(20); 
       tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); 
       return view; 
      } 
     }; 
     Intent intent = new Intent(); 
     intent.setClass(mContext, RealTime.class); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
     IntentFilter filter = new IntentFilter("Connect"); 
     filter.addAction("RecMsg"); 
     LocalBroadcastManager.getInstance(ChatActivity.this).registerReceiver(mMessageReceiver, filter); 
    } 

    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().toString().equals("Connect")) { 
       msg = (MessageReceived) intent.getExtras().getParcelable("msg"); 
       if (msg == null || msg.Message == null) 
        return; 
       listAdapter.add(msg.Destiny + "" + msg.CurrentTime + " : " + msg.Message); 
       lstChatLog.setAdapter(listAdapter); 
       realTime.SendToSpecific(msg.Sender, "Hi !", userType, obj.getRiderId(), obj.getDriverId()); 
       hideProgressDialog(); 
      } 
      else 
      if (intent.getAction().toString().equals("RecMsg")) { 
       msg = (MessageReceived) intent.getExtras().getParcelable("msg"); 
       if (msg == null || msg.Message == null) 
        return; 
       if (msg.Message.equals("*0.+9=&!*#_&1|8%digi")) { 
        lblTyping.setVisibility(View.VISIBLE); 
       } 
       else 
       if (msg.Message.equals("*0.+9=&!*#_&1|8%")) 
       { 
        lblTyping.setVisibility(View.INVISIBLE); 
       } 
       else 
       { 
        lblTyping.setVisibility(View.INVISIBLE); 
        listAdapter.add(msg.Sender + "" + msg.CurrentTime + " : " + msg.Message); 
        lstChatLog.setAdapter(listAdapter); 
        mp = MediaPlayer.create(ChatActivity.this, R.raw.notify); 
        mp.setLooping(false); 
        mp.setVolume(100, 100); 
        mp.start(); 
       } 
      } 
     } 
    }; 

    private final ServiceConnection mConnection = new ServiceConnection() { 
     @Override 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      RealTime.LocalBinder binder = (RealTime.LocalBinder) service; 
      realTime = binder.getService(); 
      mBound = true; 
      realTime.Connect(obj.getRiderName(), userType, obj.getRiderId(), obj.getLatitudeRider(), obj.getLongitudeRider(), obj.getDriverId(), obj.getVehicieId()); 
      hideProgressDialog(); 
     } 
     @Override 
     public void onServiceDisconnected(ComponentName arg0) { 
      mBound = false; 
     } 
    }; 

    @Override 
    protected void onStop() { 
     if (mBound) { 
      unbindService(mConnection); 
      mBound = false; 
     } 
     super.onStop(); 
    } 

    public void SendToSpecific(String sender, String message, String userType, long userId, long operatorId) { 
     realTime.SendToSpecific(sender, message, userType, userId,operatorId); 
     if (!message.equals("*0.+9=&!*#_&1|8%digi") && !message.equals("*0.+9=&!*#_&1|8%")) 
     { 
      time = Calendar.getInstance(); 
      listAdapter.add(spaces + sender + " " + "(" + time.get(Calendar.HOUR) + ":" + time.get(Calendar.MINUTE) + ")" + " : " + message); 
      lstChatLog.setAdapter(listAdapter); 
      txtChatMessage.setText(""); 
     } 
    } 


    @Override 
    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     if (keyCode==KeyEvent.KEYCODE_ENTER) { 
      if (txtChatMessage.getText().length() > 0) 
      { 
       InputMethodManager imm = (InputMethodManager) this.getSystemService(Context. 
         INPUT_METHOD_SERVICE); 
       if (this.getCurrentFocus() != null) 
        imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0); 
       SendToSpecific(obj.getRiderName(), txtChatMessage.getText().toString(), userType, obj.getRiderId(), obj.getDriverId()); 
      } 
     } 
     return false; 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

    } 

    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     if (txtChatMessage.getText().toString().length() > 0) { 
      if (txtChatMessage.getText().length() == 1) { 
       SendToSpecific(obj.getRiderName(), "*0.+9=&!*#_&1|8%digi", userType, obj.getRiderId(), obj.getDriverId()); 
      } 
     } else { 
      SendToSpecific(obj.getRiderName(), "*0.+9=&!*#_&1|8%", userType, obj.getRiderId(), obj.getDriverId()); 
     } 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 

    } 

    public void onClick(View v) { 

     switch (v.getId()) { 
      case R.id.btnSendChat: 
       if (txtChatMessage != null && txtChatMessage.getText().length() > 0) { 
        InputMethodManager imm = (InputMethodManager) this.getSystemService(Context. 
          INPUT_METHOD_SERVICE); 
        if (this.getCurrentFocus() != null) 
         imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0); 
        SendToSpecific(obj.getRiderName(), txtChatMessage.getText().toString(), userType, obj.getRiderId(), obj.getDriverId()); 
       } 
       break; 
     } 
    } 

    private void showProgressDialog() { 
     if (!pDialog.isShowing()) 
      pDialog.show(); 
    } 

    private void hideProgressDialog() { 
     if (pDialog.isShowing()) 
      pDialog.hide(); 
    } 

    @Override 
    protected void onDestroy() { 
     try { 
      if (pDialog != null && pDialog.isShowing()) 
       pDialog.dismiss(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     super.onDestroy(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     InputMethodManager imm = (InputMethodManager) getSystemService(Context. 
       INPUT_METHOD_SERVICE); 
     if (getCurrentFocus() != null) 
      imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     mMessageReceiver.clearAbortBroadcast(); 
     Intent i = new Intent(this, MenuPageActivity.class); 
     obj.setLastActivity("Chat"); 
     startActivity(i); 
     return true; 
    } 

    public void ShowAlert() { 
     hideProgressDialog(); 
     if (resultRequest) 
      errorMessage = "Internet is not working"; 
     alertBuilder.setTitle("Alert"); 
     alertBuilder.setMessage(errorMessage); 
     alertBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface arg0, int arg1) { 
       arg0.dismiss(); 
      } 
     }); 
     alertDialog = alertBuilder.create(); 
     alertDialog.show(); 
     errorMessage = ""; 
     resultRequest = true; 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 
    } 

} 

б) Realtime.class

package util; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.Looper; 
import android.support.v4.content.LocalBroadcastManager; 
import android.util.Log; 
import java.util.concurrent.ExecutionException; 
import br.com.yourapp.model.MessageReceived; 
import microsoft.aspnet.signalr.client.Platform; 
import microsoft.aspnet.signalr.client.SignalRFuture; 
import microsoft.aspnet.signalr.client.http.android.AndroidPlatformComponent; 
import microsoft.aspnet.signalr.client.hubs.HubConnection; 
import microsoft.aspnet.signalr.client.hubs.HubProxy; 
import microsoft.aspnet.signalr.client.hubs.SubscriptionHandler1; 
import microsoft.aspnet.signalr.client.transport.ClientTransport; 
import microsoft.aspnet.signalr.client.transport.ServerSentEventsTransport; 

public class RealTime extends Service { 
    private HubConnection mHubConnection; 
    private HubProxy mHubProxy; 
    private Handler mHandler; 
    private final IBinder mBinder = new LocalBinder(); 
    public RealTime() { } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mHandler = new Handler(Looper.getMainLooper()); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     int result = super.onStartCommand(intent, flags, startId); 
     startSignalR(); 
     return result; 
    } 

    @Override 
    public void onDestroy() { 
     mHubConnection.stop(); 
     super.onDestroy(); 
    } 
    @Override 
    public IBinder onBind(Intent intent) { 
     startSignalR(); 
     return mBinder; 
    } 

    public class LocalBinder extends Binder { 
     public RealTime getService() { 
      return RealTime.this; 
     } 
    } 

    public void Connect(String userName, String userType, long userId, double latitude, double longitude, long driverId, long vehicleId) { 
     mHubProxy.invoke("Connect", userName, userType, userId, latitude, longitude, driverId, vehicleId); 
    } 
    public void SendMessageToGroup(String userName, String userGroup, String userType, long userId, double latitude, double longitude, long vehicleId, short option) 
    { 
     mHubProxy.invoke("SendMessageToGroup", userName, userGroup, userType, userId, latitude, longitude, vehicleId, option); 
    } 

    public void SendToSpecific(String sender, String message, String userType, long userId, long operatorId)  
    { 
     mHubProxy.invoke("SendToSpecific", sender, message, userType, userId, operatorId); 
    } 

    private void startSignalR() { 
     Platform.loadPlatformComponent(new AndroidPlatformComponent()); 
     mHubConnection = new HubConnection("http://webapi.com"); 
     mHubProxy = mHubConnection.createHubProxy("ChatHub"); 
     ClientTransport clientTransport = new ServerSentEventsTransport(mHubConnection.getLogger()); 
     SignalRFuture<Void> signalRFuture = mHubConnection.start(clientTransport); 
     try { 
      signalRFuture.get(); 
     } catch (InterruptedException | ExecutionException e) { 
      Log.e("SimpleSignalR", e.toString()); 
      return; 
     } 

     mHubProxy.on("onConnected", 
       new SubscriptionHandler1<MessageReceived>() { 
        @Override 
        public void run(final MessageReceived msg) { 
         mHandler.post(new Runnable() { 
          @Override 
          public void run() { 
           Intent intent = new Intent("Connect"); 
           intent.putExtra("msg", msg); 
           LocalBroadcastManager.getInstance(RealTime.this).sendBroadcast(intent); 
          } 
         }); 
        } 
       } 
       , MessageReceived.class); 
    } 

      } 
     mHubProxy.on("ReceivedMessageServer", 
       new SubscriptionHandler1<MessageReceived>() { 
        @Override 
        public void run(final MessageReceived msg) { 
         mHandler.post(new Runnable() { 
          @Override 
          public void run() { 
           Intent intent = new Intent("RecMsg"); 
           intent.putExtra("msg", msg); 
           LocalBroadcastManager.getInstance(RealTime.this).sendBroadcast(intent); 
          } 
         }); 
        } 
       } 
       , MessageReceived.class); 

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