Android干货

这一篇是干货

这一篇是干货

这一篇是干货

本章没有重点,都是细腻的开发干货,如有需要自行取用(本人把有道云笔记中的东西分享到这)。

1.当你在低性能、反应慢的手机、平板上开发时,页面很卡,或者反应很慢的时候,你可以尝试一下增大APP的内存申请:

android:largeHeap="true"

或者同时开启硬件加速:

android:hardwareAccelerated="true"

2.ScrollerView嵌套RecyclerView滑动冲突

可以在RecyclerView设置:
setHasFixedSize(true);
setNestedScrollingEnabled(true);

或者继承RV自定义控件,主动关闭掉外层滑动控件的事件处理,直接交给里面的RV:
Android干货_第1张图片

RecyclerView默认抢焦点,并设置嵌套滑动开启,即它在被嵌套滑动使用的时候,默认放弃自己的滚动。
这也是导致滑动卡顿、不流畅的原因。

(具体方法的意义,自行去了解,本篇是干货,不做多讲解。)

3. 音量处理问题

通话音量:

int max = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);//获取最大值
int current = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);//获取当前值

媒体音量:

int max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);//获取最大值
int current = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);//获取当前值

设置通话音量:

AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setMode(AudioManager.STREAM_MUSIC);
mAudioManager.setStreamVolume(STREAM_VOICE_CALL, volumn, AudioManager.FLAG_PLAY_SOUND);

设置媒体音量:

AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int) realVolume, AudioManager.FLAG_PLAY_SOUND);

在这说明两点:

  1. 一般来说,通话音量系统不允许直接设置成0,最低可直接设置成1。
  2. 调节音量的时候不要一下子从一个大值调节值一个很小的值,或者很小的值一下子调到很大的值,这样可能会导致不生效。正确应该以1为单位去调整大小。

4.免提切换(微信免提切换功能可参考)

这里直接贴真实可用代码:

//免提
private void speakerPhone(Context context){
    AudioManager mAudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    mAudioManager.setMode(AudioManager.MODE_NORMAL);
    mAudioManager.setSpeakerphoneOn(true);
}

//手柄
private void speakHandler(Context context){
    AudioManager mAudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    mAudioManager.setSpeakerphoneOn(false);
    mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
}

//第二套切换手柄和免提的方法(兼容方法)
private void changeToincall(boolean on) {
    AudioManager mAudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    if (on) {//外放模式
        mAudioManager.setMode(AudioManager.MODE_NORMAL);
        mAudioManager.setSpeakerphoneOn(true);
        tv_satu.setText("外放模式");
    } else {//听筒模式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        } else {
            mAudioManager.setMode(AudioManager.MODE_IN_CALL);
        }
        mAudioManager.setSpeakerphoneOn(false);
        tv_satu.setText("听筒模式");
    }
}

5.设置系统时间

//curr_time 格式:MMddHHmmyyyy.ss    例:020110302018.35
    public static void setSystemTime(Context context, String curr_time) {
        try {
            AlarmManager mAlarmManager = (AlarmManager)
                    context.getSystemService(Context.ALARM_SERVICE);
            mAlarmManager.setTimeZone("Asia/Shanghai"); // Asia/Shanghai//GMT+08:00
            LogUtils.i("系统设置 开始同步服务器时间");
            execSuCmd22("date " + curr_time
                    + "\n busybox hwclock -w\n");
        } catch (Exception e) {
            LogUtils.i("系统设置 同步服务器时间失败");
            e.printStackTrace();
        }
    }
/**
     * 执行Android命令
     *
     * @param cmd 命令
     */
    private static void execSuCmd22(String cmd) {
        Process process = null;
        DataOutputStream os = null;
        DataInputStream is = null;
        try {
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd + "\n");
            os.writeBytes("exit\n");
            os.flush();
            int aa = process.waitFor();
            is = new DataInputStream(process.getInputStream());
            byte[] buffer = new byte[is.available()];
            is.read(buffer);
            String out = new String(buffer);
        } catch (Exception e) {
            Log.i("88888888", "88888888  同步服务器时间失败");
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
                if (process != null) {
                    process.destroy();
                }

            } catch (Exception e) {
            }
        }
        LogUtils.i("同步服务器时间成功");
    }

如果报权限错误,那可能需要root。目前用雷电模拟器测试过正常,我们自研设备正常。

6.重启设备

protected void adbCommond(String command) {
        try {
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
            int read;
            char[] buffer = new char[4096];
            StringBuffer output = new StringBuffer();
            while ((read = reader.read(buffer)) > 0) {
                output.append(buffer, 0, read);
            }
            reader.close();
            process.waitFor();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

调用方式:adbCommond(“reboot”);

 private void exec() {
        try {
            LogUtils.e("开始执行ADB命令");
            PowerManager pManager = (PowerManager) getSystemService(Context.POWER_SERVICE);  //重新启动到fastboot模式
            pManager.reboot("");

            //开始执行ADB命令
//            Process process = Runtime.getRuntime().exec(command);
//            process.waitFor();
//            Process process = Runtime.getRuntime().exec(command);
//            BufferedReader reader = new BufferedReader(
//                    new InputStreamReader(process.getInputStream()));
//            int read;
//            char[] buffer = new char[4096];
//            StringBuffer output = new StringBuffer();
//            while ((read = reader.read(buffer)) > 0) {
//                output.append(buffer, 0, read);
//            }
//            reader.close();
//            process.waitFor();
//            return output.toString();
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

7.视频播放(GSYVideoPlayer)

在这里介绍一下这个开源播放器,总体感觉很好。
Github: 传送门
它支持多种协议的视频流播放,本篇就以直播流RTSP为例:

public synchronized void rtspPlay(String url){
        try{
            /**此中内容:优化加载速度,降低延迟*/
            VideoOptionModel videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
            List list = new ArrayList<>();
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_flags", "prefer_tcp");
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "allowed_media_types", "video"); //根据媒体类型来配置
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 20000);
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "buffer_size", 1316);
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "infbuf", 1);  // 无限读
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100);
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 10240);
            list.add(videoOptionModel);
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1);
            list.add(videoOptionModel);
            //  关闭播放器缓冲,这个必须关闭,否则会出现播放一段时间后,一直卡主,控制台打印 FFP_MSG_BUFFERING_START
            videoOptionModel = new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);
            list.add(videoOptionModel);
            GSYVideoManager.instance().setOptionModelList(list);

            xinChengPlayer.setUp(url, true, "");


            xinChengPlayer.setGSYVideoProgressListener(new GSYVideoProgressListener() {
                @Override
                public void onProgress(int progress, int secProgress, int currentPosition, int duration) {
                    Log.i("=======","=======progress:"+progress+"====secProgress:"+secProgress+"====currentPosition:"+currentPosition+"====duration:"+duration);
                }
            });

            GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL);

            xinChengPlayer.startPlayLogic();

            show();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

了解更多点传送门哈。

8.安卓上的阴影

目前采用开源实现(比较好的解决方案):
上Git:
ShapeView

好了,本篇到此结束,都是干活,日后继续补充。有需要自行提取。

你可能感兴趣的:(android,java,android,studio)