2017-01-17 25 views
0

簡単なアプリケーションを作成しようとしています。つまり、 "Hi"のようなアンドロイドアプリでedittextに単語を書くと、アンドロイドアプリはnode.jsサーバーに "Hi"メッセージを送り、node.jsサーバーはアンドロイドアプリに "Hi sent successflly"というメッセージを送信します。これは単なる例で、実際に私のオブジェクトはアンドロイドがサーバーにデータ(メッセージ)を送信し、サーバーから別のデータ(メッセージ)を受信して​​います。node.jsサーバーからAndroidアプリにメッセージを送信するにはどうすればよいですか?

これは問題です。アンドロイドアプリに単語を書いてボタンを押すと、メッセージが正常に送信されました(コンソールでnode.jsで確認できます)。しかし、私はnode.jsからアンドロイドにメッセージを送ることはできません..私が送信ボタンを押すと、アンドロイドアプリがシャットダウンしました..

アンドロイドとは "仮想メソッドを呼び出そうとしました。 app.Activity.runOnUiThread(java.lang.Runnable) 'ヌルオブジェクトリファレンスで' ..

昨日、このエラーは発生せず、別のエラーが発生しました。 "JSONObjectに文字列をキャストできません。"

私は自分のコードを表示します。

サーバー側(Node.jsの)

var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
var port = 12000; 

app.get('/', function(req, res) { 
    res.sendFile('index.html'); 
}) 

io.on('connection', function(socket) { 
    console.log('Android device has been connected'); 
    socket.on('message', function(data) { 
     console.log('message from Android : ' + data); 

     Object.keys(io.sockets.sockets); 
     Object.keys(io.sockets.sockets).forEach(function (id) { 
      console.log("ID : ", id); 
      io.to(id).emit('message', data); 
      console.log(data + ' has sent successfully'); 
     }) 

     /*if (data != null) { 
      io.emit('message', {message : data + ' has received successfully'}); 
     }*/ 
    }) 

    socket.on('disconnect', function() { 
     console.log('Android device has been disconnected'); 
    }) 
}) 

http.listen(port, function() { 
    console.log('Server Start at port number ' + port); 
}) 

クライアント側(アンドロイド)は

private Emitter.Listener handleIncomingMessages = new Emitter.Listener(){ 
     @Override 
     public void call(final Object... args){ 
      getActivity().runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        JSONObject data = (JSONObject) args[0]; 
        String message; 
        try { 
         message = data.getString("text").toString(); 
         Log.i("result", message); 
         addMessage(message); 

        } catch (JSONException e) { 
         Log.e("result", "Error : JSONException"); 
         return; 
        } catch (ClassCastException e) { 
         Log.e("result", "Error : ClassCastException"); 
         e.printStackTrace(); 
         return; 
        } 
       } 
      }); 
     } 
    }; 

private void sendMessage(){ 
    String message = mInputMessageView.getText().toString().trim(); 
    mInputMessageView.setText(""); 
    addMessage(message); 
    JSONObject sendText = new JSONObject(); 
    try{ 
     sendText.put("text", message); 
     socket.emit("message", message); 
    }catch(JSONException e){ 

    } 
} 

private void addMessage(String message) { 

    mMessages.add(new Message.Builder(Message.TYPE_MESSAGE) 
      .message(message).build()); 
    // mAdapter = new MessageAdapter(mMessages); 
    mAdapter = new MessageAdapter(mMessages); 
    mAdapter.notifyItemInserted(0); 
    scrollToBottom(); 
} 

private void scrollToBottom() { 
    mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1); 
} 

私はすでに他の人が尋ねたという同様の問題を捜索したが、それは私に解決策を与えていません。私を助けてください。長い質問をお読みいただきありがとうございます。

p.s英語が話せないので、英語が上手ではありません。文法や文章力には多くの問題があります。理解していただきありがとうございます...

+0

は、あなたがコードをステップ実行しようとしたことがありますか?デバッガ?戦略的な場所に価値をプリントアウトする?ほとんどのコーディングは、なぜ機能しないのかを把握しているので、このスキルを習得することを強くお勧めします。 – jdv

+0

はい..私は本当にデバッギングスキルを学びたいと思っています。そして、私はデバッグスキルを学んでいます。しかし、時間がありません.2週間でこの課題を完了しなければならないので。実際には、私が尋ねたことはプロジェクトの一部に過ぎません。だから私は尋ねました。しかしあなたのアドバイスに感謝します –

+0

それで、あなたは単純に戦略的な場所で値をプリントアウトして、あなたの仮定をテストしようとしませんか?授業は学習を促進し、教材を理解していることを示すことです。ここにあなたの宿題をする人はいません。あなたが何らかの努力をして、特定の問題に関連する具体的な質問をしていることを示してください。ここはスタートです:https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ – jdv

答えて

1

理由は、getActivity()がnullを返すためです。これは、アクティビティから切り離された後、またはアクティビティがもはや見えなくなった後で、フラグメントに対してこれを実行すると発生する可能性があります。私のような前に、通常のnullチェックをするでしょう:

Activity activity = getActivity(); 
if(activity != null) { 
    activity.runOnUiThread(new Runnable() {...} 
} 

私はsocket.emit()メソッドに慣れていないんだけど、それはUIスレッドで実行されているので、それがネットワークの例外がスローされることがありますし、あなたがそれを行うことは許されません。別のスレッドでこれを行う場合は、RxJava/RxAndroidを使用することをお勧めします。あなたがネットワーク操作を行いたい場合は

はちょうどこのようにそれを使用します。

Observable 
    .fromRunnable(new Runnable { 
     void run() { 
      // here do your work 
     } 
    }) 
    .subscribeOn(Schedulers.newThread()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(new Subscriber<Void>() { 
     @Override 
     public void onCompleted() { 
      // not really needed here 
     } 

     @Override 
     public void onError(Throwable e) { 
      // handle errors on UI thread 
     } 

     @Override 
     public void onNext(Void void) { 
      // do something on UI thread after run is done 
     } 
    }); 

基本的にはそれが何をするか、それはあなただけで別のスレッドで行われコーラブルからメソッド呼び出しを呼び出し、それが上だとき、それは無い場合の方法をonNext呼び出しますSubscriberクラスから例外がスローされた場合は例外がスローされたかonErrorメソッドがスローされました。

ResponseクラスはRxJava/RxAndroid APIの一部ではなく、必要に応じて作成することができます。シンプルなPOJOクラスや必要なものにすることができます。応答が必要ない場合は、Callableの代わりにRunnableを使うことができます。うまくいくでしょう。あなたのモジュールにGradleのファイルこの依存関係を追加する必要があり、これが動作するためには

dependencies { 
    compile 'io.reactivex:rxandroid:1.2.1' 
    compile 'io.reactivex:rxjava:1.1.6' 
} 
関連する問題