EventBus3.0實現(xiàn)視頻斷點續(xù)傳功能

<p>其實,我寫文章主要是對自己學習的記錄,讓自己對所學到的知識進行歸納總結(jié),我也不知道這些文章是否對你有作用,但如果你看了,覺得有哪些不足的地方望指點,一起學習,一起進步。在我的上一篇文章我的安卓開發(fā)之路收獲到了幾個喜歡一個加油鼓勵。很是讓我感激、興奮。我也更加有信心、有毅力的堅持寫好博客。雖然最近老師一直在催論文、項目又挺著急的,但今天我要分享我的一個安卓筆記,也是從項目中總結(jié)的。
<p>最近我在做一個社交類安卓手機應用有這么一個需求:動態(tài)發(fā)表視頻、文本、圖片、位置等信息,就類似陌陌、微博等發(fā)布動態(tài)效果。今天也將這個功能實現(xiàn)了?,F(xiàn)在給你分享我的設(shè)計思路與功能實現(xiàn)主要代碼。如果你也像實現(xiàn)這樣的功能需求的話,希望這篇文章能夠幫助到你,如果你覺得有不足之處,希望你能夠指點思路。
<p>首先我的思路是從手機微博客戶端(ios)開始的,一般來說,上傳一個視頻文件還是要一定的時間的,但如果在調(diào)用發(fā)布動態(tài)接口的時候,先讓用戶在這個發(fā)布動態(tài)頁面干等的話必定會影響用戶的心情的。甚至如果時間太長的話用戶可能卸載掉你的app。因此我們必須在不影響用戶操作的情況下實現(xiàn)視頻上傳并成功調(diào)用發(fā)布動態(tài)的接口。然而調(diào)用后臺服務(wù)讓其在后臺實現(xiàn)視頻上傳并成功調(diào)用發(fā)布動態(tài)接口,大概思路就是這樣。我們項目的后臺與前臺實現(xiàn)上傳交互主要用到了--七牛云儲存--實現(xiàn)上傳功能。主要過程如下:進入發(fā)布頁面打開UploadService.class---通過視頻的絕對路徑調(diào)用服務(wù)端提供的接口獲取一個key--成功獲取key值之后銷毀這個發(fā)布界面并緩存所有需要上傳的數(shù)據(jù)--通過EventBus3.0通知服務(wù)并調(diào)用斷點續(xù)傳方法---上傳操作完成之后就調(diào)用發(fā)布動態(tài)接口---最后在動態(tài)列表界面就能刷新到你剛剛發(fā)布的數(shù)據(jù)了
首先項目至少有一個寫一個BaseActivity基類吧,并且項目中的每個頁面都繼承這個基類,然后寫一個啟動服務(wù)和注冊EventBus的方法,在需要啟動服務(wù)或者注冊EventBus的界面調(diào)用這兩個方法就能夠啟動服務(wù)和注冊了。
<p>啟動服務(wù)和注冊EventBus的方法,記得停止服務(wù)和注銷Eventbus

 if (isStartUploadService()) {
            uploadService.setAction("com.youshusoft.nowlineclient.UPLOAD_ACTION");
            uploadService.setPackage("com.youshusoft.nowlineclient.service.UploadService");//安卓L以上系統(tǒng)要
            startService(uploadService);
        }
        if (isBindEventBusHere()) {
            EventBus.getDefault().register(this);
        }

    /**
     * 是否開啟上傳服務(wù)
     *
     * @return
     */
    protected boolean isStartUploadService() {
        return false;
    }

    /**
     * 是否注冊EventBus
     *
     * @return
     */
    protected boolean isBindEventBusHere() {
        return false;
    }

獲取上傳視頻的絕對路徑之后調(diào)用服務(wù)端接口獲取key值:

  //視頻上傳
    public void UpLoadVideo(final String path) {
        File file = new File(path);
        final String key = MD5Util.getFileMD5String(file);
        videoKey = key;
        if (file.exists() && file.isFile()) {
            if (qiNiuApi == null) {
                qiNiuApi = new QiNiuApi();
            }
            qiNiuApi.getVideoUpToken(key, new RequestCallback() {
                @Override
                public void resultSuccess(Object data) {
                    if (data.toString().trim().equals("")) {
                        //已經(jīng)上傳過的話,直接調(diào)用發(fā)布動態(tài)接口
                        DynamicApi dynamicApi = new DynamicApi();
                        dynamicApi.insert(publish(), longitude, latitude, Integer.parseInt(UserInfoCache.getInstance(PublishActivity.this).getLocationDetail().getCityCode()), addStr, requestCallback);
                    } else {
                        //獲取服務(wù)端的返回的key
                        upToken = new UpToken();
                        upToken.setToken(data.toString());
                        upToken.setKey(key);
                        
                        Dynamic dynamic = new Dynamic();
                        dynamic.setContent(publish());
                        dynamic.setLn(longitude);
                        dynamic.setLa(latitude);
                        dynamic.setCity(Integer.valueOf(UserInfoCache.getInstance(PublishActivity.this).getLocationDetail().getCityCode()));
                        dynamic.setPos(addStr);
                        //緩存需要上傳的數(shù)據(jù)到本地,避免程序預料不到的異常崩潰是數(shù)據(jù)失敗,在重新打開程序的時候會用到
                        UserInfoCache.getInstance(PublishActivity.this).setUploadQuene(new UploadQueueBean(dynamic, upToken, videoPath));
                        //通知上傳服務(wù)上傳視頻
                        EventBus.getDefault().post(new MessageEvent(EventConfig.UPLOAD_VIDEO, new UploadQueueBean(dynamic, upToken, videoPath)));
                    }
                    showShortToast(R.string.publish_success);
                    finish();
                }
            });
        } else {
            LogUtils.e(getString(R.string.file_notexit));
        }
    }

<p>UploadSevice.class接受到了上傳操作的通知(參考EventBus):

  @Subscribe(threadMode = ThreadMode.POSTING)
    public void onBackgroundEventBus(MessageEvent messageEvent) {
        switch (messageEvent.getEventCode()) {
            case EventConfig.UPLOAD_VIDEO:
                message = (UploadQueueBean) messageEvent.getData();
                dynamic = message.getDynamic();
                breakpointUpload(message.getFilePath(), message.getUpToken());
                break;
        }
    }

<p>斷點續(xù)傳(參考七牛SDK):

 /**
     * 斷點續(xù)傳
     *
     * @param filePath 文件路徑
     */
    private void breakpointUpload(String filePath, UpToken upToken) {
        Recorder recorder = null;
        try {
            String sdcard = Environment.getExternalStorageDirectory().getPath();
            recorder = new FileRecorder(sdcard + "/youshusoft/nowLine/");
        } catch (IOException e) {
            //可能文件目錄不存在或沒有權(quán)限
            e.printStackTrace();
        }
        KeyGenerator keyGen = new KeyGenerator() {
            @Override
            public String gen(String key, File file) {
                return key;
            }
        };
        Configuration config = new Configuration.Builder()
                .recorder(recorder, keyGen)
                .build();
        uploadManager = new UploadManager(config);

        uploadManager.put(filePath, upToken.getKey(), upToken.getToken(), new UpCompletionHandler() {
            @Override
            public void complete(String key, ResponseInfo info, JSONObject response) {
                LogUtils.e(key + ",\r\n " + info + ",\r\n " + response);
            }
        }, new UploadOptions(null, null, false, progressHandler,
                new UpCancellationSignal() {
                    public boolean isCancelled() {
                        return false;
                    }
                }));
    }

<p>進度動態(tài)監(jiān)聽(參考七牛SDK):

 progressHandler = new UpProgressHandler() {
            @Override
            public void progress(String key, double percent) {
                progress = percent;
                if (percent == 1.0) {
                    //調(diào)用動態(tài)發(fā)布接口
                    new DynamicApi().insert(dynamic.getContent(), dynamic.getLn(), dynamic.getLa(), dynamic.getCity(), dynamic.getPos(), new RequestCallback() {
                        @Override
                        public void resultSuccess(Object data) {
                            message = null;
                            //清除上傳隊列緩存信息
                            UserInfoCache.getInstance(UploadService.this).setUploadQuene(message);
                        }
                    });
                    //通知BaseActivity 上傳完成
                    EventBus.getDefault().post(new MessageEvent(EventConfig.UPLOAD_SUCCESS));
                }
            }
        };

當上傳到成功的時候就通知BaseActivity

  /**
     * 默認情況,和發(fā)送事件在同一個線程
     *
     * @param messageEvent
     */
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onPostEventBus(MessageEvent messageEvent) {
        switch (messageEvent.getEventCode()) {
            case EventConfig.UPLOAD_SUCCESS:
                uploadService.setAction("com.youshusoft.nowlineclient.UPLOAD_ACTION");
                stopService(uploadService);
                break;
        }
    }

<p>上傳期間遇到異常崩潰的話,再次打開頁面的時候會提示是否繼續(xù)上傳操作

 if (UserInfoCache.getInstance(BaseActivity.this).getUploadQueue() != null && !isServiceWork(this, UploadService.class.getName())) {
            uploadService.setAction("com.youshusoft.nowlineclient.UPLOAD_ACTION");
            uploadService.setPackage("com.youshusoft.nowlineclient.service.UploadService");
            startService(uploadService);
            showUploadDialog();
        }

<p>EventBus信息通用類:

/**
 * Created by zhangyuting on 2016/4/6.
 */
public class MessageEvent<T> {

    /**
     * reserved data
     */
    private T data;

    /**
     * this code distinguish between different events
     */
    private int eventCode = -1;

    public MessageEvent(int eventCode) {
        this(eventCode, null);
    }

    public MessageEvent(int eventCode, T data) {
        this.eventCode = eventCode;
        this.data = data;
    }

    /**
     * get event code
     *
     * @return
     */
    public int getEventCode() {
        return this.eventCode;
    }

    /**
     * get event reserved data
     *
     * @return
     */
    public T getData() {
        return this.data;
    }
}

到此就差不多了吧。希望這篇文章能夠幫助到你,我也很希望能得到你的寶貴意見!好了我要去寫論文了,現(xiàn)在是深夜一點半!
總結(jié)了些問題
1.沒有了解透EventBus的使用??赡芤院髸佑|Rx大家族
2.與微博還是有些差距,具體的解決方案暫時沒有
3.不是干貨,但應該能用吧~~~~哈哈

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,138評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,604評論 19 139
  • 花兒,在枝頭嬉戲。 大地,張開雙臂: “回來吧,孩子!” 花兒笑著,舞著, 回到媽媽懷里, 靜靜偎依 , 安然睡去...
    悠然云舒閱讀 267評論 0 0
  • 翻轉(zhuǎn)一個鏈表 樣例:給出一個鏈表1->2->3->null,這個翻轉(zhuǎn)后的鏈表為3->2->1->null
    jose_dl閱讀 185評論 0 0
  • 近日,在貼吧上有一則帖子成為了熱門討論災區(qū)。 帖子標題是:我讓我女性發(fā)小坐了副駕駛,女朋友要跟我分手。 這位發(fā)帖的...
    桃爍爍閱讀 555評論 0 0

友情鏈接更多精彩內(nèi)容