2017-01-17 134 views
0

我試圖做一個簡單的應用程序。那就是當我在Android應用程序的edittext中編寫一個單詞時,例如「Hi」,然後android應用程序向node.js服務器發送消息「Hi」,node.js服務器向Android應用發送消息「Hi has successflly」。這只是一個例子,實際上我的對象是android向服務器發送數據(消息),並從服務器接收另一個數據(消息)。如何將消息從node.js服務器發送到Android應用程序?

問題是這樣的。當我在android應用程序上寫一個單詞並按下按鈕時,消息傳輸成功(我可以通過控制檯在node.js上確認)。但我不能從node.js發送消息到android ..當我按發送按鈕,我的android應用程序關閉..

什麼機器人說是「java.lang.NullPointerException:嘗試調用虛擬方法」無效android。 'null對象引用'上的'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

是的..我真的很想學習調試技巧..和即時學習調試技巧..但我沒有太多時間..因爲我必須在兩週內完成這項任務。其實,我問的只是項目的一部分..所以我問..但是,多謝你的建議 –

+0

因此,你不會嘗試在戰略位置打印價值來測試你的假設嗎?課程是爲了促進學習,並表明你理解這些材料。這裏沒有人會做你的功課。表明你已經做出了一些努力並提出了與具體問題有關的具體問題。這是一個開始:https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ – jdv

回答

1

發生這種情況的原因是因爲方法getActivity()返回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類或其他你需要的東西。如果你不需要回應,你可以使用Runnable而不是Callable,它可以正常工作。

爲了這個工作,你需要添加這種依賴關係,你的模塊搖籃文件:

dependencies { 
    compile 'io.reactivex:rxandroid:1.2.1' 
    compile 'io.reactivex:rxjava:1.1.6' 
} 
相關問題