2016-10-05 3 views
0

thisのようなチュートリアルをRxjavaEventBusとして使いました。しかし、彼らは私の問題を解決しません。サービスとアクティビティの間のイベントバスとしてのRxJava

私は自分のカスタムnodejsサーバーとsocket.ioを使ってチャットアプリケーションを作っています。認可は、改造(gson)で行われます。ユーザーは、アプリケーションがオフになってもメッセージを受け取るはずです。したがって、socket.ioへの接続は、それがユーザーに表示されている場合はアクティビティに情報を中継する多彩なサービスによって維持されます。 SQLデータベース(TODO)に変換します。私のServicesocket.ioから電話を受け取り、ペイロードを解析します。それが起こると、受信したペイロードと共にアクティビティにメッセージを送信する必要があります。

MyEventBus.class

public class MyRxBus { 

    private static MyRxBus instance; 

    private PublishSubject<Object> subject = PublishSubject.create(); 

    public static MyRxBus instanceOf() { 
     if (instance == null) { 
      instance = new MyRxBus(); 
     } 
     return instance; 
    } 

    /** 
    * Pass any event down to event listeners. 
    */ 
    public void setString(Object object) { 
     subject.onNext(object); 
    } 

    /** 
    * Subscribe to this Observable. On event, do something 
    * e.g. replace a fragment 
    */ 
    public Observable<Object> getEvents() { 
     return subject; 
    } 
} 

SocketServiceクラス

public class SocketService extends Service { 
    private Socket mSocket; 
    public SocketService() { 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d("SERVICE ","SOCKET SERVICE WAS CALLED"); 
     mSocket=SocketSingleton.getSocket("8080"); 
     mSocket.on(Socket.EVENT_CONNECT,onConnect); 
     mSocket.on("new_message",onNewMessage); 
     mSocket.connect(); 
    } 


    private Emitter.Listener onNewMessage = new Emitter.Listener() { 
     @Override 
     public void call(Object... args) { 
      Log.d("Received from socket ",args[0].toString()); 
      try { 
       final JSONObject object = new JSONObject((String) args[0]); 
       //Send this object to all subscribers 
       //TODO: add rxjava eventbus to 1)add info to db, 2)update activity IF it is displayed 
       MyRxBus.instanceOf() 
        .setEvent(object); 

      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 
    //some other functions (not related at all) 

} 

MainActivity.class

public class MainActivity extends VesicaActivity { 
    private Socket mSocketOne; 
    private Gson gson = new Gson(); 
    private List<ChatMessage> mMessages = new ArrayList<ChatMessage>(); 
    private List<String> mListOfUsers = new ArrayList<String>(); 
    Boolean isNodeOne; 
    String username; 
    private JSONArray arrayOfUsers=null; 
    private RecyclerView mRecyclerView; 
    private RecyclerView.Adapter mAdapter; 
    private RecyclerView.LayoutManager mLayoutManager; 
    private Boolean _isConnected=false; 
    private String socketIdtoSend; 

    @BindView(R.id.et_text)EditText etText; 
    @BindView(R.id.tv_user_list)TextView tvListUsers; 
    @BindView(R.id.tv_status)TextView tvStatus; 
    @BindView(R.id.toolbar)Toolbar toolbar; 
    @BindView(R.id.et_self_destruct_time)EditText etSelfDestructTimer; 
    @BindView(R.id.cb_self_destruct)CheckBox cbSelfDestruct; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ButterKnife.bind(this); 
     setSupportActionBar(toolbar); 
     if (getSupportActionBar()!=null){ 
      getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     } 
     tvStatus.setText("checking connection..."); 
     username = Constants.getUsername(); 
     Integer portNumber = Constants.getPortNumber(); 
     socketIdtoSend = getIntent().getStringExtra("socketId"); 
     mMessages.add(createMessage("Sample Name","Sample Text",0)); 
     mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     mLayoutManager = new LinearLayoutManager(this); 
     mRecyclerView.setLayoutManager(mLayoutManager); 
     mAdapter = new ChatAdapter(mMessages, username); 
     mRecyclerView.setAdapter(mAdapter); 


     //----------------------------------------------------------------- 

     MyRxBus.instanceOf() 
       .getEvents() 
       .subscribe(new Action1<Object>() { 
        @Override 
        public void call(Object o) { 
         final JSONObject object = new JSONObject((String) o) 
         ChatMessage message = createMessage(object.getString("user") 
           ,Encryption.Decrypt(object.getString("message")) 
           ,object.getInt("selfDestructTime")); 
         mMessages.add(message); 
         mAdapter.notifyDataSetChanged(); 
         Toast.makeText(MainActivity.this," new message received ", Toast.LENGTH_SHORT).show(); 
        } 
       }); 

    } 


    public ChatMessage createMessage(String user, String message, Integer time){ 
     return new ChatMessage.ChatMessageBuilder() 
       .message(message) 
       .user(user) 
       .type("newMessage") 
       .selfDestructTime(time) 
       .sendToSocketId(socketIdtoSend) 
       .build(); 
    } 


    public void showDialogBoxToClearHistory(){ 
     new AlertDialog.Builder(MainActivity.this) 
       .setTitle("Wipe Chat History") 
       .setMessage("This will delete the entire chat history of this thread. It is irreversible. Do you want to continue?") 
       .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         // continue with delete 
         mMessages.clear(); 
         mAdapter.notifyDataSetChanged(); 
         Toast.makeText(MainActivity.this, "Cleared entire history", Toast.LENGTH_LONG).show(); 
        } 
       }) 
       .setNegativeButton("Skip", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         try{ 
          dialog.dismiss(); 
         }catch (Exception e){e.printStackTrace();} 
        } 
       }) 
       .setCancelable(false) 
       .show(); 
    } 

    private void ScrollToBottom(){ 
     mRecyclerView.smoothScrollToPosition(mAdapter.getItemCount()); 
    } 
} 

私はこのコードを実行すると、私は次のエラー rx.exceptions.OnErrorNotImplementedException: Can't create handler inside thread that has not called Looper.prepare()

を取得します私は観測とオブザーバーはしかし、試行錯誤の多くの後、私はあきらめて、いくつかの助けを必要としている、異なるスレッドの観察/発光するように設定することができることを承知しています at com.example.varun.vesica.eventbus.MyRxBus.setEvent(MyRxBus.java:26)

を指す

助けてください/リンクはありがとうございます。ありがとう!

答えて

0

常にメンテナンスを行うと、ユーザーのバッテリーが消耗します。デバイスがブロックされているかアプリが最小化されているときにプッシュ通知を使用することを検討する必要があります。 アクティビティでObservableを購読すると、サブスクリプションを保存してonPauseで閉じます。そうでない場合は、デバイスのローテーションによって接続が滞っています。 GreenRobotイベントバスを使用しての代わりに、車輪の再発明を検討し、それがサービスとアクティビティを接続するための非常に便利なライブラリです:http://www.andreas-schrade.de/2015/11/28/android-how-to-use-the-greenrobot-eventbus/

+0

Socket.ioがはるかにバッテリーを消耗しません。プッシュ通知を使用すると、私のチャットプロトコルにsocket.ioを使用する目的が無効になります。チャットアプリケーションにGCMを使用することにはいくつかの欠点があります。 RxJavaの追加の利点は、GreenRobotに比べると無視しすぎています。すでに私はテキストビューをバインドするためにこれを使用しています。 はいサブスクリプションはonPauseで削除されます。私は(ほとんどのアプリのように)デバイスの回転を無効にしました。 –

+0

あなたはバターナイフを意味しますか?アクティビティのコードにEventBusはありません –

+0

Butterknifeはビューバインド用です。 RxJavaは、テキストビューのテキストウォッチャーとして使用できます。上記の誤字をおかけして申し訳ありません。基本的に私はRxJavaをアプリで使っていますが、GreenRobotが何でもできることを行うことができるので、それに固執したいと思います。例として、RxJavaをアプリケーション用のログインページに使用しました。UIの応答性が高く、コードが従来のアプローチよりも短くなっています。 –

0

あなたは、任意のスレッドがsetEvent()/setString()を呼び出したものは何でも上adapter.notifyDataSetChanged()Toast.makeText()を呼び出そうとしています。 あなたがAndroidのUIを更新することを目標に、あなたのgetEvents()、観察を購読すると、あなたは、メインスレッドスケジューラに観察する必要があります。

MyRxBus.instanceOf() 
      .getEvents() 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Action1<Object>() { 
       @Override 
       public void call(Object o) { 
        final JSONObject object = new JSONObject((String) o) 
        ChatMessage message = createMessage(object.getString("user") 
          ,Encryption.Decrypt(object.getString("message")) 
          ,object.getInt("selfDestructTime")); 
        mMessages.add(message); 
        mAdapter.notifyDataSetChanged(); 
        Toast.makeText(MainActivity.this," new message received ", Toast.LENGTH_SHORT).show(); 
       } 
      }); 
+0

これを試しますが、イベントを消費するアクティビティクラスではなく、サービスクラスで呼び出されたsetEvent()でエラーがスローされています。 –

+0

ランダムなスレッドから 'onNext()'を呼び出し、Toastを表示して同じエラーを受け取ることで同様のアプローチを試みました。スタックトレースはイベントソース(あなたのケースのサービスクラス)を指していて、サブスクリプションのToast呼び出しを指し示す「原因:」を持っています。 – npace

関連する問題