java與android通信
① 怎樣實現android和javaweb數據交互
要想運行網頁上的js腳本,webview必須設置支持Javas cript。
Java代碼
1mWebview.getSettings().setJavas criptEnabled(true);
然後是設置webview要載入的網頁:
web的網頁:webView.loadUrl("http://www.google.com");
本地的網頁:webView.loadUrl("file:///android_asset/XX.html"); //本地的存放在:assets文件夾中
webview做完基本的初始化後我們還要要給它,加進一個回調的代理類Javas criptInterface,並給它一個調用的名稱:ncp
Java代碼
1mWebView.addJavas criptInterface(new Javas criptInterface(),"ncp");
Javas criptInterface可以是一個普通的Java類,類實現的方法,均可被js回調:
Java代碼
final class Javas criptInterface {
public int callOnJs() {
return 1000;
}
public void callOnJs2(String mode) {
//TODO
}
}
Java要調用js的方法,只需知道js的方法名稱即可:
Java代碼
1mWebView.loadUrl("javas cript:onSaveCallback()");
js 這邊就更簡單:
Js代碼
window.onload = function(){
document.getElementById('btn_1').addEventListener('click', onBtnClick, false);
var _int_value = window.ncp.callOnJs();
alert("get int from java:" + _int_value );
}
function onBtnClick() {
window.ncp.callOnJs2("click");
}
Java和js交互有以下一些特點:
1.Java 調用 js 裡面的函數,速度並不令人滿意,大概一次一兩百毫秒吧,如果要做交互性很強的事情,這種速度會讓人瘋掉的。而反過來就不一樣了, js 去調 java 的方法,速度很快,基本上 40-50 毫秒一次。所以盡量用 js 調用 java 方法,而不是 java 去調用 js 函數。
2.Java 調用 js 的函數,沒有返回值,而 Js 調用 java 方法,可以有返回值。返回值可以是基本類型、字元串,也可以是對象。如果是字元串,有個很討厭的問題,第 3 點我會講的。如果是對象,這個對象會被轉換為 js 的對象,直接可以訪問裡面的方法。但是我不推薦 java 返回給 js 的是對象,除非是必須。因為 js 收到 java 返回的對象,會產生一些交換對象,而如果這些對象的數量增加到了 500 或 600 以上,程序就會出問題。所以盡量返回基本數據類型或者字元串。
3.Js 調用 Java 的方法,返回值如果是字元串,你會發現這個字元串是 native 的,不能對它進行一些修改操作,比如想對它 substr ,取不到。怎麼解決呢?轉成 locale 的。使用 toLocaleString() 函數就可以了。不過這個函數的速度並不快,轉化的字元串如果很多,將會很耗費時間。
② android客戶端如何與後台java伺服器交互
php做前端,java做後端淘寶是個例子伺服器端前後分開是為了兩方面,雖然淘寶最開始並不想這樣做。。。先說下歷史,淘寶是最開始php全部,後來發現開銷太大,代碼效率不行,就直接把數據存儲啊,用戶通知啊就交給java實際上大部分網站都樂意採用這種前端php後端java或者c++這種形式,我是phpc++這種。優點,核心動作效率肯定高,c++java這種代碼效率奇高。比php腳本好很多。前端php,語法簡單,維護簡單,部署簡單,而且容易找到維護人員。總之就是開發快,維護成本低。大致了解了嗎?你說的h5+java實際上就是把java提到前台,不是不可以,維護和開發成本太高了啊。前端開發要經常搞,但是java做前台要調試、編譯部署還要重編譯。麻煩,人工開銷也大。不劃算如果是.net技術就更高成本了。光伺服器軟體一塊就要多少了。所以微軟的框架用的不多。國內外都不多,用.met的成本開發維護都麻煩。要氣硬體條件還苛刻。
③ java伺服器推送消息給android
幾種常見的解決方案實現原理
1)輪詢(Pull)方式:客戶端定時向伺服器發送詢問消息,一旦伺服器有變化則立即同步消息。
2)SMS(Push)方式:通過攔截SMS消息並且解析消息內容來了解伺服器的命令,但這種方式一般用戶在經濟上很難承受。
3)持久連接(Push)方式:客戶端和伺服器之間建立長久連接,這樣就可以實現消息的及時行和實時性。
3、消息推送解決方案概述
A、C2DM雲端推送方案
在Android手機平台上,Google提供了C2DM(Cloudto Device Messaging)服務。Android
Cloud to Device Messaging (C2DM)是一個用來幫助開發者從伺服器向Android應用程序發送數據的服務。該服務提供了一個簡單的、輕量級的機制,允許伺服器可以通知移動應用程序直接與伺服器進行通信,以便於從伺服器獲取應用程序更新和用戶數據。
該方案存在的主要問題是C2DM需要依賴於Google官方提供的C2DM伺服器,由於國內的網路環境,這個服務經常不可用。
B、MQTT協議實現Android推送
採用MQTT協議實現Android推送功能也是一種解決方案。MQTT是一個輕量級的消息發布/訂閱協議,它是實現基於手機客戶端的消息推送伺服器的理想解決方案。
wmqtt.jar
是IBM提供的MQTT協議的實現。我們可以從這里(https://github.com/toku/AndroidPushNotificationsDemo)下載該項目的實例代碼,並且可以找到一個採用PHP書寫的伺服器端實現(https://github.com/toku/PhpMQTTClient)。
C、RSMB實現推送功能
Really Small Message Broker (RSMB)
,是一個簡單的MQTT代理,同樣由IBM提供,其查看地址是:http://www.alphaworks.ibm.com/tech/rsmb。預設打開1883埠,應用程序當中,它負責接收來自伺服器的消息並將其轉發給指定的移動設備。SAM是一個針對MQTT寫的PHP庫。我們可以從這個http://pecl.php.net/package/sam/download/0.2.0地址下載它.
D、XMPP協議實現Android推送
Google官方的C2DM伺服器底層也是採用XMPP協議進行的封裝。XMPP(可擴展通訊和表示協議)是基於可擴展標記語言(XML)的協議,它用於即時消息(IM)以及在線探測。這個協議可能最終允許網際網路用戶向網際網路上的其他任何人發送即時消息。
androidpn是一個基於XMPP協議的java開源Android push notification實現。它包含了完整的客戶端和伺服器端。但也存在一些不足之處:
1)
比如時間過長時,就再也收不到推送的信息了。
2)性能上也不夠穩定。
3)如果將消息從伺服器上推送出去,就不再管理了,不管消息是否成功到達客戶端手機上。
如果我們要使用androidpn,則還需要做大量的工作,需要理解XMPP協議、理解Androidpn的實現機制,需要調試內部存在的BUG。
④ JAVA服務端android客戶端如何通信
一、HTTP請求(APACHE的HttpClient實現)
伺服器端,就是普通的servlet、Strutus2就可以
移動端
protected static String get(String url, List<NameValuePair> params) {
String resultMsg;
// 設置http請求配置
HttpParams parms = new BasicHttpParams();
parms.setParameter("charset", HTTP.UTF_8);
// 配置連接超時
HttpConnectionParams.setConnectionTimeout(parms, 10 * 1000);
// 設置請求超時
HttpConnectionParams.setSoTimeout(parms, 15 * 1000);
// 實例化HttpClient
HttpClient httpclient = new DefaultHttpClient(parms);
// 實例化HttpGet
HttpGet httpget = new HttpGet(url);
// 設置請求頭
httpget.addHeader("Content-Type", "application/json");
httpget.addHeader("charset", HTTP.UTF_8);
try {
if (params.size() > 0)
url = url + "?" + URLEncodedUtils.format(params, HTTP.UTF_8);
HttpResponse resp = httpclient.execute(httpget);
int statusCode = resp.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
StringBuffer result = getResponse(resp);
resultMsg = result.toString();
} else {
resultMsg = "連接異常";
}
} catch (Exception e) {
resultMsg = "連接異常";
} finally {
// 關閉get
httpget.abort();
// 關閉連接 ,釋放資源
httpclient.getConnectionManager().shutdown();
}
return resultMsg;
}
protected static String post(String uri, Object params) {
String resultMsg;
// 設置http請求配置
HttpParams hp = new BasicHttpParams();
hp.setParameter("charset", HTTP.UTF_8);
// 配置連接超時
HttpConnectionParams.setConnectionTimeout(hp, 10 * 1000);
HttpConnectionParams.setSoTimeout(hp, 15 * 1000);
// 實例化HttpClient
HttpClient httpclient = new DefaultHttpClient(hp);
// 實例化HttpPost請求
HttpPost httppost = new HttpPost(uri);
// 設置頭信息
httppost.addHeader("Content-Type", "application/json");
httppost.addHeader("charset", HTTP.UTF_8);
try {
// 將參數進行json化
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(params);
Log.i(TAG, "URI=" + uri + ",BEAN=" + jsonStr);
// 定義消息實體
StringEntity se = new StringEntity(jsonStr, HTTP.UTF_8);
httppost.setEntity(se);
// 通信
HttpResponse resp = httpclient.execute(httppost);
int statusCode = resp.getStatusLine().getStatusCode();
Log.i(TAG, "StatusCode=" + statusCode);
if (statusCode == HttpStatus.SC_OK) {
StringBuffer result = getResponse(resp);
resultMsg = result.toString();
} else {
resultMsg = "連接異常";
}
} catch (Exception e) {
e.printStackTrace();
resultMsg = "連接異常";
} finally {
// 關閉get
httppost.abort();
// 關閉連接 ,釋放資源
httpclient.getConnectionManager().shutdown();
}
Log.i(TAG, resultMsg);
return resultMsg;
}
二、SOCKET連接
伺服器端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class service_java_test {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(10000); //綁定的埠號
Socket socket = server.accept(); //連接不成功以至於下一行的"連接成功"
//在調試區顯示不出來
System.out.println("連接成功");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
while (true) {
String msg = in.readLine();
System.out.println(msg);
out.println("Server received " + msg); //向接收方發送已接受到了的語句
out.flush();
if (msg.equals("bye")) { //若接收到"bye"則break
break;
}
}
socket.close();
}
}
安卓客戶端:
package com.example.t4_android;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView myTextView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView = (TextView) findViewById(R.id.textView1);
Thread t = new Thread(new Runnable(){
public void run(){
try {
Socket sk = new Socket("192.168.253.1", 10000);//綁定套接字,這一行一直執行不成功
//以至於下一行在安卓頁面的TextView上
//不顯示「已連接」的字樣
//"192.168.253.1"是我利用DOS命令查找
//的本機IP
myTextView.setText("已連接");
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
}
}
⑤ 如何干凈的實現Android/Java Socket 長連接通信
Java Socket通信有很多的時候需要我們不斷的學習。方面效率雖然不及C與C++但它以靈活語言優勢,為大家廣為使用。 本文就對在使用java做通信方面程序時候應改注意問題做以說明。1.長連接、短鏈接只是針對客戶端而言,伺服器無所謂長、短;2.無論同步或者非同步通信,發送之後務必要又響應回復,確認收到,負責進行一定范圍內重發,例如重發三次;3.長連接伺服器與客戶端之間務必需要心跳探測,由客戶端主動發起;4.短連接伺服器通用代碼:
package com.biesan.sms.gate.unioncom.communication;
import com.biesan.commons.Constants;
import com.biesan.commons.util.CodeUtil;
import com.biesan.sms.gate.unioncom.data.*;
import com.biesan.sms.gate.unioncom.util.GateInfo;
import java.net.*;
import java.io.*;
import java.util.*;
import org.apache.log4j.*;
import spApi.*;
public class UnioncomDeliver extends Thread {
// stop flag
private boolean unInterrupt = true;
private boolean unErr = true;
//private boolean closeSocketFlag = false;
// server socket
private ServerSocket serverSo = null;
// current socket
private Socket so = null
private OutputStream output = null;
private InputStream input = null;
// gate command
private SGIP_Command tmpCmd = null;
private SGIP_Command cmd = null;
private Bind bind = null;
private BindResp bindResp = null;
//private Unbind unBind = null;
private UnbindResp unBindResp = null;
private boolean unAcceptErrorFlag = true;
Logger unioncomLog = Logger.getLogger(Unioncom
Deliver.class.getName());
public UnioncomDeliver() {
}
public void run() {
unioncomLog.info("Start...");
while (unInterrupt) {
this.initServer();
this.startServices();
while (this.unAcceptErrorFlag) {
try {
//接受連接請求
unioncomLog.info("before accept connection!.......
FreeMemroy :" + Runtime.getRuntime().freeMemory());
this.acceptConnection();
unioncomLog.info("after accept connection!.......
FreeMemroy :" + Runtime.getRuntime().freeMemory());
while (unErr) {
cmd = new Command();
unioncomLog.info("before read command from stream
........... FreeMemroy: " + Runtime.getRuntime().
freeMemory());
tmpCmd = cmd.read(input);
unioncomLog.info("after read command from stream " +
getCommandString(cmd.getCommandID()) + " FreeMemroy: " +
Runtime.getRuntime().freeMemory());
if (tmpCmd == null) {
unErr = false;
break;
}
switch (cmd.getCommandID()) {
// biad ready communication
case SGIP_Command.ID_SGIP_BIND: {
this.dealBind();
break;
}// exit bind
case SGIP_Command.ID_SGIP_UNBIND: {
this.dealUnBind();
unioncomLog.info("after unbind connection!.......
FreeMemroy :" + Runtime.getRuntime().freeMemory());
break;
}// deliver
....
default : //錯誤的命令字
break;
}// switch
}// while(unErr)
} catch (Exception e) {
unioncomLog.error("Unioncom Recv Service Error"
+ e.getMessage());
} finally {
if (this.so != null) {
this.closeSocket();
}
this.unErr = true;
}
}// while (this.unAcceptErrorFlag)
try {
this.closeServerSocket();
sleep(200);// sleep
} catch (InterruptedException ie) {
}
}// while(unInterrupt)
}
private String getCommandString(int cmd){
switch (cmd) {
// biad ready communication
case SGIP_Command.ID_SGIP_BIND: {
return " BIND COMMAND ";
}// exit bind
case SGIP_Command.ID_SGIP_UNBIND: {
return " UNBIND COMMAND ";
}// deliver
case ...
default:
return " UNKNOWN COMMAND";
}
}
private void dealBind() {
try {
bind = new Bind(tmpCmd);
if (bind.readbody() != 0) {
unioncomLog.warn("Read Bind error");
this.unErr = false;
}
bindResp = new BindResp(tmpCmd.getMsgHead());
bindResp.SetResult(0);
bindResp.write(output);
unioncomLog.debug("Bind success!");
} catch (Exception e) {
unioncomLog.error("Dela Union Recv Bind Error!" +
e.getMessage());
this.unErr = false;
}
}
private void dealUnBind() {
try {
//unBind = (Unbind) tmpCmd;
unBindResp = new UnbindResp(tmpCmd.getMsgHead());
unBindResp.write(output);
unioncomLog.debug("UnBind success!");
} catch (Exception e) {
unioncomLog.warn("Unbind error!" + e.getMessage());
}
this.unErr = false;
}
private void startServices() {
boolean unStartServices = true;
while (unStartServices) {
try {
serverSo = new ServerSocket(ugInfo.getLocalServerPort(), 5,
InetAddress.getByName(ugInfo.getLocalIpAdd()));
//serverSo.setSoTimeout(60000);
unStartServices = false;
unioncomLog.info("Create union recv socket Ok!");
} catch (IOException e) {
unioncomLog.warn("Create union recv socket error!"
+ e.getMessage());
unStartServices = true;
UnioncomSubmit.thrSlp(3000);
}
}
}
private void acceptConnection() {
// Accept 失敗
try {
so = serverSo.accept();
so.setSoTimeout(10000);
} catch (Exception e) {
unioncomLog.warn("Accept Error!" + e.getMessage());
this.closeServerSocket();
this.unAcceptErrorFlag = false;
this.unErr=false;
}
// Accept成功
try {
input = so.getInputStream();
output = so.getOutputStream();
} catch (IOException e) {
unioncomLog.warn("Get I/O stream Error!" + e.getMessage());
this.closeService();
this.unAcceptErrorFlag = false;
this.unErr=false;
}
}
private void closeSocket() {
try {
so.close();
unioncomLog.info("Socket Close Success!!!");
} catch (Exception e) {
unioncomLog.error("Socket Close Failure!!!" + e.getMessage());
}
}
private void closeServerSocket() {
try {
serverSo.close();
unioncomLog.info("ServerSocket Close Success!!!");
} catch (Exception e) {
unioncomLog
.error("ServerSocket Close Failure!!!" + e.getMessage());
}
}
private void closeService() {
this.closeSocket();
this.closeServerSocket();
}
private void initServer() {
this.bind = null;
this.bindResp = null;
//this.unBind = null;
this.unBindResp = null;
this.tmpCmd = null;
this.cmd = null;
this.serverSo = null;
this.so = null;
this.output = null;
this.input = null;
this.unErr = true;
//this.closeSocketFlag = false;
unioncomLog.info("Memory***==="
+ java.lang.Runtime.getRuntime().freeMemory());
}
public synchronized void requireStop() {
this.unInterrupt = false;
unioncomLog.info("Requre interrupt!!!");
}
public String convertMsgContentCoding
(int msgCoding, byte[] msgContent) {
String deliverContent = null;
try {
if (msgContent != null) {
if (msgCoding == 8) { // 處理ucs32編碼
deliverContent = new String(msgContent,
"UnicodeBigUnmarked");
} else if (msgCoding == 0) { // 處理ASCII編碼
deliverContent = new String(msgContent, "ASCII");
} else if (msgCoding == 4) { // 處理binary編碼
deliverContent = new String(msgContent);
} else if (msgCoding == 15) { // 處理GBK編碼
deliverContent = new String(msgContent, "GBK");
// 處理DELIVER數據包的簡訊息ID
} else {
unioncomLog.error("編碼格式錯誤!");
return "";
}
} else
return "";
return deliverContent;
} catch (UnsupportedEncodingException ex) {
unioncomLog.error("deal content error!" +
ex.getMessage());
return "";
}
}
}