大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學(xué)習攻略 Java學(xué)習 Java消息推送框架的代碼

Java消息推送框架的代碼

更新時間:2022-07-28 11:49:55 來源:動力節(jié)點 瀏覽1890次

大家在Java教程中會學(xué)到關(guān)于Java消息推送的知識,那么,Java消息推送框架的代碼是什么?動力節(jié)點小編來為大家解答。

1.主要是兩種實現(xiàn)方式:

(1)pull:輪詢,輪詢時間短:耗電,耗流量。時間長,不能保證消息及時。

輪詢:

Timer:WakeLock 讓CPU 保持喚醒,耗電量很大

AlarmManager:管理獨立的硬件時鐘RTC,可以在CPU休眠的時候正常運行。在預(yù)設(shè)的時間到達之后,喚醒CPU。這樣CPU可以正常休眠,只需要任務(wù)到達之后醒來一段很短的時間。極光推送就是基于此實現(xiàn)的。

(2)push:SMS、長連接。

2.長連接又包括三種方式:

(1)GCM:google的Gcm,容易被國內(nèi)廠商閹割,而且NAT(Network AddressTranslation)容易超時,長連接無法保持,造成消息推送延遲。

(2)第三方推送:友盟、極光,騰訊信鴿

(3)自定義長連接:長連接、心跳和推送及時率。

保持長連接,是消息及時的重要保證。發(fā)送心跳包,如果前臺檢測發(fā)送失敗,則重新初始化一個socket。

3.把socket鏈接和心跳功能都放在一個Service中,為什么要放在Service中?

一般我們這種socket幾乎是跟app的生命周期一樣長,甚至更長。不管在不在Service中去完成操作,我們都得開異步線程,雖然Service并不是異步操作,但是為了提升我們?nèi)蝿?wù)的優(yōu)先級,我們最好是放在Service中,因為Service是由Android系統(tǒng)管理的,并且擁有比較高的優(yōu)先級,線程是Java中的異步任務(wù)載體,可以說android系統(tǒng)不太認識線程。放在Service中可以很大程度上避免任務(wù)被回收或者關(guān)閉

4.下面是android代碼的具體實現(xiàn):

BackSevice服務(wù):

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
public class BackService extends Service {
    private static final String TAG = "BackService";
    /** 心跳檢測時間  */
    private static final long HEART_BEAT_RATE = 3 * 1000;
    /** 主機IP地址  */
    private static final String HOST = "192.168.1.104";
    /** 端口號  */
    public static final int PORT = 9800;
    /** 消息廣播  */
    public static final String MESSAGE_ACTION = "org.feng.message_ACTION";
    /** 心跳廣播  */
    public static final String HEART_BEAT_ACTION = "org.feng.heart_beat_ACTION";
    private long sendTime = 0L;
    /** 弱引用 在引用對象的同時允許對垃圾對象進行回收  */
    private WeakReference<Socket> mSocket;
    private ReadThread mReadThread;
    private IBackService.Stub iBackService = new IBackService.Stub() {
        @Override
        public boolean sendMessage(String message) throws RemoteException {
            return sendMsg(message);
        }
    };
    @Override
    public IBinder onBind(Intent arg0) {
        return (IBinder) iBackService;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        new InitSocketThread().start();
    }
    // 發(fā)送心跳包
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                boolean isSuccess = sendMsg("");// 就發(fā)送一個\r\n過去, 如果發(fā)送失敗,就重新初始化一個socket
                if (!isSuccess) {
                    mHandler.removeCallbacks(heartBeatRunnable);
                    mReadThread.release();
                    releaseLastSocket(mSocket);
                    new InitSocketThread().start();
                    Log.d("ztf"," 發(fā)送失敗,就重新初始化一個socket" );
                }
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };
    public boolean sendMsg(String msg) {
        if (null == mSocket || null == mSocket.get()) {
            return false;
        }
        Socket soc = mSocket.get();
        try {
            if (!soc.isClosed() && !soc.isOutputShutdown()) {
                OutputStream os = soc.getOutputStream();
                String message = msg + "\r\n";
                os.write(message.getBytes());
                os.flush();
                sendTime = System.currentTimeMillis();// 每次發(fā)送成功數(shù)據(jù),就改一下最后成功發(fā)送的時間,節(jié)省心跳間隔時間
                Log.i(TAG, "發(fā)送成功的時間:" + sendTime);
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    // 初始化socket
    private void initSocket() throws UnknownHostException, IOException {
        Socket socket = new Socket(HOST, PORT);
        mSocket = new WeakReference<Socket>(socket);
        mReadThread = new ReadThread(socket);
        mReadThread.start();
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);// 初始化成功后,就準備發(fā)送心跳包
    }
    // 釋放socket
    private void releaseLastSocket(WeakReference<Socket> mSocket) {
        try {
            if (null != mSocket) {
                Socket sk = mSocket.get();
                if (!sk.isClosed()) {
                    sk.close();
                }
                sk = null;
                mSocket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    class InitSocketThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                initSocket();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public class ReadThread extends Thread {
        private WeakReference<Socket> mWeakSocket;
        private boolean isStart = true;
        public ReadThread(Socket socket) {
            mWeakSocket = new WeakReference<Socket>(socket);
        }
        public void release() {
            isStart = false;
            releaseLastSocket(mWeakSocket);
        }
        @SuppressLint("NewApi")
        @Override
        public void run() {
            super.run();
            Socket socket = mWeakSocket.get();
            if (null != socket) {
                try {
                    InputStream is = socket.getInputStream();
                    byte[] buffer = new byte[1024 * 4];
                    int length = 0;
                    while (!socket.isClosed() && !socket.isInputShutdown()
                            && isStart && ((length = is.read(buffer)) != -1)) {
                        if (length > 0) {
                            String message = new String(Arrays.copyOf(buffer,
                                                                      length)).trim();
                            Log.i(TAG, "收到服務(wù)器發(fā)送來的消息:"+message);
                            // 收到服務(wù)器過來的消息,就通過Broadcast發(fā)送出去
                            if (message.equals("ok")) {// 處理心跳回復(fù)
                                Intent intent = new Intent(HEART_BEAT_ACTION);
                                sendBroadcast(intent);
                            } else {
                                // 其他消息回復(fù)
                                Intent intent = new Intent(MESSAGE_ACTION);
                                intent.putExtra("message", message);
                                sendBroadcast(intent);
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Activity:

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    private Intent mServiceIntent;
    private IBackService iBackService;
    private TextView tv;
    private EditText et;
    private Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
        initData();
    }
    private void initViews() {
        tv = (TextView) findViewById(R.id.resule_text);
        et = (EditText) findViewById(R.id.content_edit);
        btn = (Button) findViewById(R.id.send);
    }
    private void initData() {
        mServiceIntent = new Intent(this, BackService.class);
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String string = et.getText().toString().trim();
                Log.i(TAG, string);
                try {
                    Log.i(TAG, "是否為空:" + iBackService);
                    if (iBackService == null) {
                        Toast.makeText(getApplicationContext(),
                                       "沒有連接,可能是服務(wù)器已斷開", Toast.LENGTH_SHORT).show();
                    } else {
                        boolean isSend = iBackService.sendMessage(string);
                        Toast.makeText(MainActivity.this,
                                       isSend ? "success" : "fail", Toast.LENGTH_SHORT)
                             .show();
                        et.setText("");
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    @Override
    protected void onStart() {
        super.onStart();
        bindService(mServiceIntent, conn, BIND_AUTO_CREATE);
        // 開始服務(wù)
        registerReceiver();
    }
    @Override
    protected void onResume() {
        super.onResume();
        // 注冊廣播 最好在onResume中注冊
        // registerReceiver();
    }
    @Override
    protected void onPause() {
        super.onPause();
        // 注銷廣播 最好在onPause上注銷
        unregisterReceiver(mReceiver);
        // 注銷服務(wù)
        unbindService(conn);
    }
    // 注冊廣播
    private void registerReceiver() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BackService.HEART_BEAT_ACTION);
        intentFilter.addAction(BackService.MESSAGE_ACTION);
        registerReceiver(mReceiver, intentFilter);
    }
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // 消息廣播
            if (action.equals(BackService.MESSAGE_ACTION)) {
                String stringExtra = intent.getStringExtra("message");
                tv.setText(stringExtra);
            } else if (action.equals(BackService.HEART_BEAT_ACTION)) {// 心跳廣播
                tv.setText("正常心跳");
            }
        }
    };
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // 未連接為空
            iBackService = null;
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 已連接
            iBackService = IBackService.Stub.asInterface(service);
        }
    };
}

aidl文件:

interface IBackService{
    boolean sendMessage(String message);
}

5.android系統(tǒng)的推送和iOS的推送有什么區(qū)別

首先我們必須知道,所有的推送功能必須有一個客戶端和服務(wù)器的長連接,因為推送是由服務(wù)器主動向客戶端發(fā)送消息,如果客戶端和服務(wù)器之間不存在一個長連接那么服務(wù)器是無法來主動連接客戶端的。因而推送功能都是基于長連接的基礎(chǔ)是上的。

IOS長連接是由系統(tǒng)來維護的,也就是說蘋果的IOS系統(tǒng)在系統(tǒng)級別維護了一個客戶端和蘋果服務(wù)器的長鏈接,IOS上的所有應(yīng)用上的推送都是先將消息推送到蘋果的服務(wù)器然后將蘋果服務(wù)器通過這個系統(tǒng)級別的長連接推送到手機終端上,這樣的的幾個好處為:

在手機終端始終只要維護一個長連接即可,而且由于這個長連接是系統(tǒng)級別的不會出現(xiàn)被殺死而無法推送的情況。

省電,不會出現(xiàn)每個應(yīng)用都各自維護一個自己的長連接。

安全,只有在蘋果注冊的開發(fā)者才能夠進行推送,等等。

android的長連接是由每個應(yīng)用各自維護的,但是google也推出了和蘋果技術(shù)架構(gòu)相似的推送框架,C2DM,云端推送功能,但是由于google的服務(wù)器不在中國境內(nèi),其他的原因你懂的。所以導(dǎo)致這個推送無法使用,android的開發(fā)者不得不自己去維護一個長鏈接,于是每個應(yīng)用如果都24小時在線,那么都得各自維護一個長連接,這種電量和流量的消耗是可想而知的。雖然國內(nèi)也出現(xiàn)了各種推送平臺,但是都無法達到只維護一個長連接這種消耗的級別。

以上就是關(guān)于“Java消息推送框架的代碼”介紹,大家如果想了解更多相關(guān)知識,可以關(guān)注一下動力節(jié)點的Java視頻教程,里面的課程內(nèi)容從入門到精通,細致全面,通俗易懂,很適合沒有基礎(chǔ)的小白學(xué)習,希望對大家能夠有所幫助。

提交申請后,顧問老師會電話與您溝通安排學(xué)習

免費課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 亚洲一区精品视频在线 | 看一级毛片 | 精品欧美一区二区三区在线 | 97免费在线观看 | 国产v欧美v日韩在线观看 | 天天操天天干天天爽 | 国产亚洲精品一区二区久久 | 成人一级视频 | 在线观看一级毛片免费 | 欧美亚洲日本国产 | 99久久精品免费看国产情侣 | 欧美日韩在线观看免费 | 久热在线视频精品网站 | 欧美一级看片a免费视频 | 欧美另类丰满69xxxxx | 在线成人aa在线看片 | 亚洲一区二区三区欧美 | 日韩毛片基地一区二区三区 | 在线欧美69v免费观看视频 | 成人三级视频在线观看 | 中文字幕日本精品一区二区三区 | 日日躁夜夜躁狠狠天天 | 国产精品视频久久久久 | 亚洲酷色综合 | 亚洲七七久久精品中文国产 | 狠狠操天天爱 | 韩国日本三级在线观看 | 一级大黄视频 | 欧美香蕉爽爽人人爽观看猫咪 | 久操这里只有精品 | 激情福利网 | 免费观看日本a毛片 | 成 人 黄 色 视频 免费观看 | 老司机午夜免费影院 | 欧美成人一区二免费视频 | 天天综合天天综合 | 国产香蕉一区二区在线网站 | 国产精品日本一区二区不卡视频 | 欧美一级欧美三级在线观看 | 天天操夜夜操夜夜操 | 欧美一区二区三区精品影视 |