• Android开发之科大讯飞语音合成与播报



    今天做一个稍微复杂点的,Android集成科大讯飞实现语音合成与播报功能。
    老规矩,直接进入正题。

    一、效果图

    在这里插入图片描述

    二、打开讯飞开放平台,注册登录后,找到我的应用,点击创建新应用。

    在这里插入图片描述

    三、填写相关信息,然后点击提交。

    在这里插入图片描述

    四、点击创建好的应用。

    在这里插入图片描述

    五、可以看到APPID信息。

    在这里插入图片描述

    六、往下滑可以下载SDK。

    在这里插入图片描述

    七、下载到本地后,解压。

    在这里插入图片描述
    这里重点就是这个libs文件夹中的内容了。

    八、把刚才解压后的libs中的文件复制到项目中的libs下。

    在这里插入图片描述

    1.此时这个Msc.jar还是不可用的,下面鼠标右键点击它。

    在这里插入图片描述

    2.点击Add As Library…

    在这里插入图片描述

    3.点击OK,此时你可以看到它可以展开了,就说明你的app模块中已经添加了这个jar的依赖了。

    在这里插入图片描述

    九、复制assets文件夹到项目中。

    在这里插入图片描述

    十、粘贴到main下面,如下图所示。

    在这里插入图片描述

    十一、配置项目,打开build.gradle。

    	//资源设置
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    十二、AndroidManifest.xml中配置权限。

    	<!--连接网络权限,用于执行云端语音能力 -->
        <uses-permission android:name="android.permission.INTERNET"/>
        <!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
        <uses-permission android:name="android.permission.RECORD_AUDIO"/>
        <!--读取网络信息状态 -->
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <!--获取当前wifi状态 -->
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
        <!--允许程序改变网络连接状态 -->
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
        <!--读取手机信息权限 -->
        <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
        <!--外存储写权限,构建语法需要用到此权限 -->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <!--外存储读权限,构建语法需要用到此权限 -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    十三、新建一个MyApplication类。

    在这里插入图片描述

    package com.example;
    
    import android.app.Application;
    
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechUtility;
    import org.xutils.x;
    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            SpeechUtility.createUtility(MyApplication.this, SpeechConstant.APPID +"=\n" +
                    "7b6e5ba7");
            super.onCreate();
            x.Ext.init(this);
            x.Ext.setDebug(BuildConfig.DEBUG);  //这个会影响性能
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.然后在AndroidManifest.xml中配置

    在这里插入图片描述

    十四、主布局文件(activity_yy)

    在这里插入图片描述

    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="750dp"
        android:orientation="vertical">
        <include layout="@layout/main_title_bar"/>
        <EditText
            android:id="@+id/et_text"
            android:gravity="top|left"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/Theme.TYLDApp"/>
    
        <Button
            android:id="@+id/btn_play"
            android:text="开始播放"
            android:layout_width="200dp"
            android:textSize="20dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:background="@drawable/register_selector"
            android:layout_marginLeft="100dp"
            android:textColor="@color/white"/>
        <Button
            android:id="@+id/btn_cancel"
            android:text="取消"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textColor="@color/white"
            android:textSize="20dp"
            android:background="@drawable/register_selector"
            android:layout_marginLeft="100dp"/>
    
        <Button
            android:id="@+id/btn_pause"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:textColor="@color/white"
            android:textSize="20dp"
            android:background="@drawable/register_selector"
            android:layout_marginLeft="100dp"
            android:layout_marginTop="10dp"
            android:text="暂停播放" />
    
        <Button
            android:id="@+id/btn_resume"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:textColor="@color/white"
            android:textSize="20dp"
            android:background="@drawable/register_selector"
            android:layout_marginLeft="100dp"
            android:layout_marginTop="10dp"
            android:text="继续播放" />
        <LinearLayout
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:paddingStart="6dp"
            android:paddingEnd="6dp">
    
            <View
                android:layout_width="0dp"
                android:layout_height="0.5dp"
                android:layout_weight="1"
                android:background="#000" />
    
            <TextView
                android:layout_marginStart="6dp"
                android:layout_marginEnd="6dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置"
                android:textColor="#000"
                android:textSize="16sp" />
    
            <View
                android:layout_width="0dp"
                android:layout_height="0.5dp"
                android:layout_weight="1"
                android:background="#000" />
        LinearLayout>
    
        
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingStart="6dp"
            android:paddingEnd="6dp">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置发音人:"
                android:textColor="#000"
                android:textSize="16sp" />
    
            <Spinner
                android:id="@+id/spinner"
                android:layout_width="0dp"
                android:layout_height="50dp"
                android:layout_weight="1" />
        LinearLayout>
        
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center_vertical"
            android:paddingStart="6dp"
            android:paddingEnd="6dp">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置语速:"
                android:textColor="#000"
                android:textSize="16sp" />
    
            <SeekBar
                android:id="@+id/sb_speed"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:max="100"
                android:progress="50" />
        LinearLayout>
    
        
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center_vertical"
            android:paddingStart="6dp"
            android:paddingEnd="6dp">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置音调:"
                android:textColor="#000"
                android:textSize="16sp" />
    
            <SeekBar
                android:id="@+id/sb_pitch"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:max="100"
                android:progress="50" />
        LinearLayout>
    
        
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:gravity="center_vertical"
            android:paddingStart="6dp"
            android:paddingEnd="6dp">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置音量:"
                android:textColor="#000"
                android:textSize="16sp" />
    
            <SeekBar
                android:id="@+id/sb_volume"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:max="100"
                android:progress="50" />
        LinearLayout>
    
    LinearLayout>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181

    十五、主java文件(YybbActivity)

    package com.example.activity;
    
    
    import static com.iflytek.cloud.VerifierResult.TAG;
    
    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.graphics.Color;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.MemoryFile;
    import android.text.Spannable;
    import android.text.SpannableStringBuilder;
    import android.text.style.BackgroundColorSpan;
    import android.util.Log;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.ActivityCompat;
    
    import com.example.R;
    import com.iflytek.cloud.ErrorCode;
    import com.iflytek.cloud.InitListener;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechError;
    import com.iflytek.cloud.SpeechEvent;
    import com.iflytek.cloud.SpeechSynthesizer;
    import com.iflytek.cloud.SynthesizerListener;
    import com.iflytek.cloud.msc.util.FileUtil;
    import com.iflytek.cloud.msc.util.log.DebugLog;
    
    import java.util.Vector;
    
    public class YybbActivity extends AppCompatActivity implements View.OnClickListener,AdapterView.OnItemSelectedListener {
        //语速
        private String speedValue = "50";
        //音调
        private String pitchValue = "50";
        //音量
        private String volumeValue = "50";
        //输入框
        private EditText etText;
        // 语音合成对象
        private SpeechSynthesizer mTts;
        // 默认发音人
        private String voicer = "xiaoyan";
        //发音人名称
        private static final String[] arrayName = {"讯飞小燕", "讯飞许久", "讯飞小萍", "讯飞小婧", "讯飞许小宝"};
    
        //发音人值
        private static final String[] arrayValue = {"xiaoyan", "aisjiuxu", "aisxping", "aisjinger", "aisbabyxu"};
    
        //数组适配器
        private ArrayAdapter<String> arrayAdapter;
        // 引擎类型
        private String mEngineType = SpeechConstant.TYPE_CLOUD;
        //播放的文字
        String text = " 属性:昔刘涓子晋末于丹阳郊外照射,忽见一物,高二丈许,射而中之,如雷电声若风雨。其夜不敢前追,诘旦率门徒子弟数人,寻纵至山下,见一小儿提罐,问何往为。";
        private Vector<byte[]> container = new Vector<>();
        //内存文件
        MemoryFile memoryFile;
        //总大小
        public volatile long mTotalSize = 0;
      
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_yy);
             //请求权限
            requestPermissions();
            initView();
            // 初始化合成对象
            mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener);
        }
        /**
         * 初始化页面
         */
        private void initView() {
            etText = findViewById(R.id.et_text);
            findViewById(R.id.btn_play).setOnClickListener(this);
            findViewById(R.id.btn_cancel).setOnClickListener(this);
            findViewById(R.id.btn_pause).setOnClickListener(this);
            findViewById(R.id.btn_resume).setOnClickListener(this);
           SeekBar sbSpeed = findViewById(R.id.sb_speed);
            SeekBar sbPitch = findViewById(R.id.sb_pitch);
            SeekBar sbVolume = findViewById(R.id.sb_volume);
            Spinner spinner = findViewById(R.id.spinner);
             //将可选内容与ArrayAdapter连接起来
            arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, arrayName);
            //设置下拉列表的风格
            arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            //将adapter 添加到spinner中
            spinner.setAdapter(arrayAdapter);
            //添加事件Spinner事件监听
            spinner.setOnItemSelectedListener(this);
    
            setSeekBar(sbSpeed, 1);
            setSeekBar(sbPitch, 2);
            setSeekBar(sbVolume, 3);
        }
    
        /**
         * 请求权限
         */
        private void requestPermissions() {
            try {
                //Android6.0及以上版本
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    int permission = ActivityCompat.checkSelfPermission(this,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE);
                    if (permission != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(this, new String[]
                                {Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                        Manifest.permission.WRITE_SETTINGS,
                                        Manifest.permission.READ_EXTERNAL_STORAGE}, 0x0010);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /**
         * 权限请求返回结果
         */
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
        /**
         * 页面点击事件
         * @param v 控件
         */
        @Override
        public void onClick(View v) {
            if (mTts == null) {
                this.showTip("创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化");
                return;
            }
            switch (v.getId()) {
                case R.id.btn_play://开始合成
                    //输入文本
                    String etStr = etText.getText().toString().trim();
                    if (!etStr.isEmpty()) {
                        text = etStr;
                    }
                    //设置参数
                    setParam();
                    //开始合成播放
                    int code = mTts.startSpeaking(text, mTtsListener);
                    if (code != ErrorCode.SUCCESS) {
                        showTip("语音合成失败,错误码: " + code);
                    }
                    break;
    
                case R.id.btn_cancel://取消合成
                    mTts.stopSpeaking();
                    break;
                case R.id.btn_pause://暂停播放
                    mTts.pauseSpeaking();
                    break;
                case R.id.btn_resume://继续播放
                    mTts.resumeSpeaking();
                    break;
    
                default:
                    break;
            }
        }
        /**
         * 初始化监听。
         */
        private InitListener mTtsInitListener = new InitListener() {
            @Override
            public void onInit(int code) {
                Log.i(TAG, "InitListener init() code = " + code);
                if (code != ErrorCode.SUCCESS) {
                    showTip("初始化失败,错误码:" + code);
                } else {
                    showTip("初始化成功");
                }
            }
        };
        /**
         * Toast提示
         * @param msg
         */
        private void showTip(String msg) {
            Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
        }
        /**
         * 参数设置
         *
         * @return
         */
        private void setParam() {
            // 清空参数
            mTts.setParameter(SpeechConstant.PARAMS, null);
            // 根据合成引擎设置相应参数
            if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
                mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
                //支持实时音频返回,仅在synthesizeToUri条件下支持
                mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY, "1");
                // 设置在线合成发音人
                mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);
                 //设置语速
                mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);
                //设置音调
                mTts.setParameter(SpeechConstant.PITCH, pitchValue);
                //设置音量
                mTts.setParameter(SpeechConstant.VOLUME, volumeValue);
            } else {
                mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
                mTts.setParameter(SpeechConstant.VOICE_NAME, "");
            }
            // 设置播放合成音频打断音乐播放,默认为true
            mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "false");
            // 设置音频保存路径,保存音频格式支持pcm、wav
            mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "pcm");
            mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, getExternalFilesDir(null) + "/msc/tts.pcm");
        }
        /**
         * 合成回调监听。
         */
        private SynthesizerListener mTtsListener = new SynthesizerListener() {
            //开始播放
            @Override
            public void onSpeakBegin() {
                Log.i(TAG, "开始播放");
            }
    
            //暂停播放
            @Override
            public void onSpeakPaused() {
                Log.i(TAG, "暂停播放");
            }
    
            //继续播放
            @Override
            public void onSpeakResumed() {
                Log.i(TAG, "继续播放");
            }
    
            //合成进度
            @Override
            public void onBufferProgress(int percent, int beginPos, int endPos, String info) {
                Log.i(TAG, "合成进度:" + percent + "%");
            }
    
            //播放进度
            @Override
            public void onSpeakProgress(int percent, int beginPos, int endPos) {
                // 播放进度
                Log.i(TAG, "播放进度:" + percent + "%");
                SpannableStringBuilder style = new SpannableStringBuilder(text);
                style.setSpan(new BackgroundColorSpan(Color.RED), beginPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                etText.setText(style);
            }
    
            //播放完成
            @Override
            public void onCompleted(SpeechError error) {
                if (error == null) {
                    Log.i(TAG, "播放完成," + container.size());
                    DebugLog.LogD("播放完成," + container.size());
                    for (int i = 0; i < container.size(); i++) {
                        //写入文件
                        writeToFile(container.get(i));
                    }
                    //保存文件
                    FileUtil.saveFile(memoryFile, mTotalSize, getExternalFilesDir(null) + "/1.pcm");
                } else {
                    //异常信息
                    showTip(error.getPlainDescription(true));
                }
            }
            /**
             * 写入文件
             */
            private void writeToFile(byte[] data) {
                if (data == null || data.length == 0) {
                    return;
                }
                try {
                    if (memoryFile == null) {
                        Log.i(TAG, "memoryFile is null");
                        String mFilepath = getExternalFilesDir(null) + "/1.pcm";
                        memoryFile = new MemoryFile(mFilepath, 1920000);
                        memoryFile.allowPurging(false);
                    }
                    memoryFile.writeBytes(data, 0, (int) mTotalSize, data.length);
                    mTotalSize += data.length;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
            //事件
            @Override
            public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
                //	 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
                //	 若使用本地能力,会话id为null
                if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                    String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                    Log.i(TAG, "session id =" + sid);
                }
    
                //当设置SpeechConstant.TTS_DATA_NOTIFY为1时,抛出buf数据
                if (SpeechEvent.EVENT_TTS_BUFFER == eventType) {
                    byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER);
                    Log.i(TAG, "bufis =" + buf.length);
                    container.add(buf);
                }
            }
    
        };
    /**
         * 选中
         */
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            voicer = arrayValue[position];
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
        //设置SeekBar
        private void setSeekBar(SeekBar seekBar, final int type) {
    
            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    switch (type) {
                        case 1://设置语速 范围 1~100
                            speedValue = Integer.toString(progress);
                            break;
                        case 2://设置音调  范围 1~100
                            pitchValue = Integer.toString(progress);
                            break;
                        case 3://设置音量  范围 1~100
                            volumeValue = Integer.toString(progress);
                            break;
                        default:
                            break;
                    }
                }
    
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) { }
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) { }
            });
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358

    到这里就结束了,你可以试试哦

  • 相关阅读:
    使用python第三方库Parameterized进行接口参数化测试
    R3Live系列学习(四)R2Live源码阅读(2)
    头歌——机器学习——逻辑回归如何实现分类
    阿里云云效流水线教程
    数据链路层:以太网/ARP协议
    社交变革:探索Facebook如何塑造我们的日常生活
    APP启动流程二(源码30)之APP进程创建
    Chapter 3 New Optimizers for Deep Learning
    Airtest的多图查找与两图对比
    【数仓基础(一)】基础概念:数据仓库【用于决策的数据集合】的概念、建立数据仓库的原因与好处
  • 原文地址:https://blog.csdn.net/qq_61963074/article/details/126556997