0

我想了解這個東西是如何工作的更好一點。LocalBroadcastReceiver + IntentService是否是正確的做法?

因此,我學習了有關Runnables和Threads和ASyncTasks的內容,但顯然當涉及旋轉屏幕等配置更改時,它們有一些嚴重的缺陷。

對於任何應該在後臺運行的任何應用程序(比如SQL數據庫命令,文件系統過程,Internet輸入/輸出過程等)使用IntentService,然後使用LocalBroadcastReceiver將結果傳遞迴Activity,更好嗎?

+0

當然,一個例子將有助於 – user7025005

回答

0

是更好地改用IntentService任何東西應該像SQL的數據庫命令,文件系統程序,網絡輸入/輸出處理等後臺運行 - 然後用LocalBroadcastReceiver通過結果反饋給活動?

如果您的用戶界面可能會在工作進行時移動到背景,並且您擔心在工作進行時您的流程可能會被終止,那麼需要一個服務。如果工作可能超過一秒左右,我傾向於擔心這一點。否則,一個普通的線程就足夠了。

使用事件總線(如LocalBroadcastManager)是讓其他組件知道服務/線程何時完成其工作的合理方法。 This sample app演示了這一點。就我個人而言,我傾向於使用greenrobot的EventBus — this sample app是第一個的克隆,但使用EventBus而不是LocalBroadcastManager

+0

但什麼停止從一個線程過程中間旋轉手機的人? – user7025005

+0

@ user7025005:沒有。但線程不在乎。您正在使用活動巴士讓相關方知道狀態的變化。這樣的一方將在事件總線上註冊更新(例如,在LocalBroadcastManager上調用registerReceiver()),然後做一些事情來獲得當前狀態(例如檢查單例緩存管理器)。 – CommonsWare

0

遵循使用運行服務中的類的一個活動(聊天活動)的聊天示例(實時類)。我使用mvc webapi來控制聊天人之間的聊天。當實時接收消息「onConnected」或「ReceivedMessageServer」時,由LocalBroadcastManager自動發送到聊天活動。這種方式從BroadcastReceiver的「onReceive」中接收消息並運行其他任務。

一)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); 
    } 

} 

B)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); 

}