APP开发流程实例讲解-儒释道网络电台八天开发全程-优化排错:增强稳定性和添加异常处理

APP开发流程实例讲解-儒释道网络电台八天开发全程

优化排错:增强稳定性和添加异常处理

APP开发流程实例讲解-儒释道网络电台八天开发全程

  1. 项目发起
  2. 功能和界面初步设定
  3. 在Android Studio中完成界面设计
  4. 实现功能代码:播放控制
  5. 优化排错:增强稳定性和添加异常处理
  6. 界面美化并进一步优化排错
  7. 百度云深度兼容测试并进一步优化排错
  8. 签名发布

在启动时检测网络状态

先增加检测网络状态的权限

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
然后用下面的代码检测是否连接有网络

    /**
     * 检测网络是否可用
     * @return
     */
    public boolean isNetworkConnected() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        return ni != null && ni.isConnected();
    }
在onCreate中检测网络状态,如果没连网,则提示没有网络连接,退出程序。


增加VideoView状态提示和错误处理

增加正在载入数据的提示

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                @Override
                public boolean onInfo(MediaPlayer mediaPlayer, int what, int extra) {
                    if(what==MediaPlayer.MEDIA_INFO_BUFFERING_START ){
                        Toast.makeText(MainActivity.this,
                                "正在缓冲",
                                Toast.LENGTH_LONG).show();
                    }
                    return false;
                }
            });
        }
处理三类网络错误:服务器断开、网络文件未找到、超时。对于出错时的处理,这里只是提示用户,并没有强制关闭程序。因为很有可能是线路选择有问题,只需要选择合适的线路就可以了。

        videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
                    /*
                    错误常数

MEDIA_ERROR_IO
文件不存在或错误,或网络不可访问错误
值: -1004 (0xfffffc14)

MEDIA_ERROR_MALFORMED
流不符合有关标准或文件的编码规范
值: -1007 (0xfffffc11)

MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK
视频流及其容器不适用于连续播放视频的指标(例如:MOOV原子)不在文件的开始.
值: 200 (0x000000c8)

MEDIA_ERROR_SERVER_DIED
媒体服务器挂掉了。此时,程序必须释放MediaPlayer 对象,并重新new 一个新的。
值: 100 (0x00000064)

MEDIA_ERROR_TIMED_OUT
一些操作使用了过长的时间,也就是超时了,通常是超过了3-5秒
值: -110 (0xffffff92)

MEDIA_ERROR_UNKNOWN
未知错误
值: 1 (0x00000001)

MEDIA_ERROR_UNSUPPORTED
比特流符合相关编码标准或文件的规格,但媒体框架不支持此功能
值: -1010 (0xfffffc0e)


what 	int: the type of error that has occurred:
    MEDIA_ERROR_UNKNOWN
    MEDIA_ERROR_SERVER_DIED
extra 	int: an extra code, specific to the error. Typically implementation dependent.
    MEDIA_ERROR_IO
    MEDIA_ERROR_MALFORMED
    MEDIA_ERROR_UNSUPPORTED
    MEDIA_ERROR_TIMED_OUT
    MEDIA_ERROR_SYSTEM (-2147483648) - low-level system error.

* */
                if(what==MediaPlayer.MEDIA_ERROR_SERVER_DIED){
                    //媒体服务器挂掉了。此时,程序必须释放MediaPlayer 对象,并重新new 一个新的。
                    Toast.makeText(MainActivity.this,
                            "网络服务错误",
                            Toast.LENGTH_LONG).show();
                }else if(what==MediaPlayer.MEDIA_ERROR_UNKNOWN){
                    if(extra==MediaPlayer.MEDIA_ERROR_IO){
                        //文件不存在或错误,或网络不可访问错误
                        Toast.makeText(MainActivity.this,
                                "网络连接错误",
                                Toast.LENGTH_LONG).show();
                    } else if(extra==MediaPlayer.MEDIA_ERROR_TIMED_OUT){
                        //超时
                        Toast.makeText(MainActivity.this,
                                "网络超时",
                                Toast.LENGTH_LONG).show();
                    }
                }
                return false;
            }
        });

动态计算ListView的高度

    public void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

对播放和暂停进行统一控制

将播放的暂停的操作,写到了下面这个函数里进行统一管理。

    private void resetVideoView(boolean toPlay){
        if(!isNetworkConnected()){
            Toast.makeText(this, "未连接网络,程序将关闭。请连网后重新打开本程序。", Toast.LENGTH_LONG).show();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //没有连接到网络,关系程序
                    finish();
                }
            }).start();
        }else {
            if (toPlay) {
                if (videoView.isPlaying()) {
                    videoView.suspend();
                }

                if (onlySound) {
                    videoView.setVisibility(View.VISIBLE);
                    videoView.setBackgroundResource(R.drawable.zcgt);
                    videoView.setVideoURI(data.getServers().getSoundUriAuto());
                } else {
                    videoView.setBackgroundResource(0);
                    videoView.setVideoURI(data.getServers().getVideoUriAuto());
                }
                videoView.start();
                bt_play.setImageResource(android.R.drawable.ic_media_pause);
            } else {
                if (videoView.isPlaying()) {
                    videoView.suspend();
                }
                videoView.setBackgroundResource(0);
                bt_play.setImageResource(android.R.drawable.ic_media_play);
            }

        }
    }

增加等待对话框

            //打开等待初始化的对话框
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    proDialog = ProgressDialog.show(MainActivity.this, "载入数据", "数据加载中...");
                }
            });
在载入数据结束后,然后关闭进度对话框

                            //结束等待
                            proDialog.dismiss();

获取网络数据错误处理

首先在给 OkHttp3 设置超时,这个我已经在另一篇文章里做了详细说明(《OkHttp3超时设置和超时异常捕获 》)。

并在代码中检测超时。超时次数超过一定限制后返回空值。

同时检测正则表达式的返回结果。

    public void GetNote(IStringEvent noteEvent) {
        this.noteEvent = noteEvent;
        noteLoadTimes = 0;
        Request request = new Request.Builder()
                .url(noteUrl)
                .build();

        client.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                if(e.getCause().equals(SocketTimeoutException.class) && noteLoadTimes<maxLoadTimes)
                {
                    noteLoadTimes++;
                    client.newCall(call.request()).enqueue(this);
                }else {
                    e.printStackTrace();
                    WebApi.this.noteEvent.getMsg(null);
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String html = new String(response.body().bytes(), "utf8");
                Matcher m = noteItemPattern.matcher(html);
                StringBuilder sb = new StringBuilder();
                while (m.find()){
                    String nm = m.group(1);
                    if(nm.startsWith("<")) {
                        Matcher hm = htmlTagPattern.matcher(nm);
                        nm = hm.replaceAll("");
                    }
                    sb.append(nm).append("\r\n");
                }
                WebApi.this.noteEvent.getMsg(sb.toString());
            }
        });
    }


今天的工作就到这里吧。

APP程序能跑了,哈哈



源码地址 https://code.csdn.net/do168/buddhismnetworkradio


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值