【Android开发】移动程序设计复习大纲

《移动程序设计》复习大纲

考试题型和分值:

一、判断题(共10小题,每题1分,共10分)

二、单选题(共10小题,每题1分,共10分)

三、填空题(共10小题,每空1分,共10分)

四、简答题 (共4小题,每题10分,共40分)

五、程序设计题 (共2小题,每空2分,共30分)

知识点:

第一章:(涉及题型:判断题、单选题、填空题、简答题

1. Android体系结构包含的层次及各层的特点。

a)    应用程序层:一个核心应用程序的集合,安装在手机中的应用程序都属于这一层。

b)    应用程序架构层:主要提供了构建应用程序时用到的各种API。例如活动管理器(Activity Manager)。

c)    核心类库:主要包含了系统库和Android运行环境。

d)    Linux内核:他为Android设备的各种硬件提供了底层的驱动,如:显示驱动。

2. Dalvik虚拟机的特点与作用。

主要负责完成对象生命周期管理、堆栈管理、线程管理、安全和异常管理,以及垃圾回收等。

Dalvik虚拟机具有以下特点:

  • 使用dex格式的字节码,不兼容Java字节码格式
  • 代码密度小,运行效率高,节省资源
  • 常量池只使用32位的索引
  • 有内存限制
  • 默认栈大小是12KB(3个页,每页4KB)

3. AndroidManifest.xml清单文件的作用。

AndroidManifest.xml是Android应用程序的配置文件,它描述了应用程序的基本信息和组件,以及应用程序的权限和功能。

  • 定义应用程序的基本信息,如包名、应用程序名称、版本号等。
  • 声明应用程序需要的权限,如访问互联网、读取外部存储等。
  • 定义应用程序的组件,如活动、服务、广播接收器等。
  • 配置应用程序的特性,如屏幕方向、支持的屏幕大小等。

4. Android项目资源文件夹的目录结构。

  • layout:存放所有的布局文件,包括活动和片段的XML文件。
  • values:存放所有的资源文件,如字符串、颜色、尺寸等。
  • drawable:存放所有的图片资源,如位图和矢量图。
  • raw:存放原始的资源文件,如音频、视频等。
  • assets:存放其他非XML的资源文件,如文本文件、JSON文件等。

5. Android中常用的尺寸单位dp和sp的区别。

  • dp是基于屏幕密度的独立像素单位,用于在不同密度的屏幕上保持一致的物理尺寸。
  • sp是基于字体大小的独立像素单位,用于在不同屏幕密度和字体大小的设备上保持一致的文本大小

6. Android程序调试的两种方法:单元测试,logcat日志输出。

第二章:(涉及题型:判断题、单选题、填空题)

1. Android中的几种常用布局及其各自的特点。

  1. RelativeLayout(相对布局):该布局是通过相对位置的方式指定该布局内子控件的位置。
  2. LinearLayout(线性布局):该布局可通过android:orientation属性指定该布局内的子控件水平和竖直排列。
  3. TableLayout(表格布局):采用行、列的形式来管理控件。他通常搭配TableRow布局使用,一个TableRow代表一行,在TableRow中添加的控件代表一列。
  4. FrameLayout(帧布局):该布局会在屏幕上创建一块空白区域,添加到该区域中的每个子控件占一帧,这些帧会一个一个叠加在一起,后加入的控件会叠加在上一个控件上层。默认情况下,帧布局中的所有控件会与左上角对齐。
  5. ConstraintLayout(约束布局):适用于可视化的方式编写界面布局,具有相对定位、居中定位和倾向、Chain等性质。

2. 界面布局的几个通用属性的名称与功能

android:id、android:layout_width、android:layout_height、android:background、android:layout_margin、android:padding。

3. 线性布局LinearLayout的两个常用属性的名称与功能

android:orientation:决定了子元素是垂直排列还是水平排列(vertical、horizontal)

android:layout_weight:通过设置该属性值,可使布局内的控件按照权重比显示大小

4. TableLayout与LinearLayout的父子关系。

TableLayout继承自LinearLayout,因此它完全支持LinearLayout所支持的属性。

第三章:(涉及题型:判断题、单选题、填空题、简答题

1. TextView控件的常用属性名称与功能

android:text、android:textColor、android:textSize、android:gravity。

2. EditText控件的常用属性名称与功能

android:hint:当EditText为空时,显示的提示文本。当用户开始输入时,提示文本会消失。

3. EditText、Button与TextView的父子关系。TextView是Button和EditText的父类

4. 实现Button按钮的点击事件有哪几种不同方式?

  1. 在布局文件中指定android:onclick属性的方式设置点击事件。
  2. 使用匿名内部类的方式设置点击事件。
  3. 通过为Activity实现View.OnClickListener接口的方式设置点击事件。

5. ImageView控件的两个常用属性android:background与android:src功能及区别。

android:background主要用于设置背景(可以是颜色、渐变色、位图等),而android:src主要用于设置显示的图片。

6. RadioButton和RadioGroup的关系及使用方法。

  • 关系:RadioButton和RadioGroup是Android中用于实现单选按钮的组件。RadioButton是单选按钮,而RadioGroup是单选按钮组,可以包含多个RadioButton。当用户点击一个RadioButton时,其它的RadioButton会被自动取消选中。
  • 使用方法:首先在XML布局文件中定义一个或多个RadioButton,然后将它们放在一个RadioGroup中。在Java或Kotlin代码中,可以通过findViewById()方法获取到这些组件,并设置监听器来响应用户的点击事件。

7. ListView控件的基本特点以及数据适配器的作用。

  • 基本特点:ListView是一个可滚动的列表视图,可以显示多个项目,每个项目都可以是一个自定义的视图(View)。它允许用户通过上下滚动来查看所有的项目。
  • 数据适配器的作用:ListView的数据适配器是一个重要的组件,它负责将数据源(如数组、列表等)与ListView的视图进行绑定。

数据适配器的主要作用包括:

  1. 将数据源中的数据映射到ListView的每个视图中。
  2. 定义每个视图的布局和显示方式。
  3. 当数据源发生变化时,通知ListView更新视图以反映最新的数据状态。
  4. 实现列表项的点击事件等交互行为。

8. ListView与RecyclerView的区别。

1、展示效果:RecyclerView控件可以通过LayoutManager类实现横向或竖向的列表效果、瀑布流效果和GridView效果,而ListView控件只能实现竖直的列表效果。

2、适配器:RecyclerView控件使用的是RecyclerView.Adapter适配器,该适配器将BaseAdapter中的getView()方法拆分为onCreateViewHolder()方法和onBindViewHolder()方法,强制使用ViewHolder类,使代码编写规范化,避免了初学者写的代码性能不佳。

3、复用效果:RecyclerView控件复用Item对象的工作由该控件自己实现,而ListView控件复用Item对象的工作需要开发者通过convertView的setTag()方法和getTag()方法进行操作。

4、动画效果:RecyclerView控件可以通过setItemAnimator()方法为Item添加动画效果,而ListView并没有实现动画效果,但我们可以在Adapter自己实现item的动画效果。

第四章:(涉及题型:判断题、单选题、填空题、程序设计题

1. Activity有哪些生命周期方法及什么时候被调用?

1onCreate():Activity创建时调用,通常做一些初始化设置。

2、onStart():Activity即将可见时调用。

3、onResume():Activity获取焦点时调用。

4、onPause():当前Activity被其他Activity覆盖或屏幕锁屏时调用。

5、onStop():Activity对用户不可见时调用。

6、onDestroy():Activity销毁时调用。

7、onRestart():Activity从停止状态到再次启动时调用。

2. Activity组件的基本方法:setContentView、findViewById。

3. Activity组件显式调用和隐式调用的定义与区别。

  1. 显式调用是通过组件名来完成的调用,隐式调用是通过意图过滤器(IntentFilter)来实现的,它没有明确指出目标组件的名称。
  2. 显式调用需要明确地指定被启动对象的组件信息,包括包名和类名,而隐式调用则不需要明确指定组件信息。

4. Activity组件之间互相调用的基本方法:startActivity、startActivityForResult、setResult、onActivityResult。

5. 通过意图对象intent在不同的Activity之间传递数据的方法。

首先需要创建一个Intent对象,并使用putExtra()方法将需要传递的数据附加到Intent对象中。然后,通过调用startActivity()方法并将Intent对象作为参数传入,即可实现数据的传递。

假设有两个Activity:A和B。现在需要在A中获取一些数据,然后将这些数据传递给B。可以在A中创建一个Intent对象,将数据放入Intent对象中,然后启动B。在B中,可以从Intent对象中取出A传递过来的数据。如果需要返回数据给上一个活动,可以使用startActivityForResult()方法代替startActivity()方法。这样,当从B返回到A时,就可以在onActivityResult()方法中获取到返回的数据。

6. Android任务栈的特点。Activity有几种不同的启动模式?

Android任务栈是一种栈结构,具有后进先出的特点,用于存放Activity。当打开一个新的Activity时,新的Activity会被存放到栈顶位置,只有栈顶的Activity才能与用户进行交互。当栈顶的Activity结束后,界面会回退到任务栈中的上一个Activity。当一个任务栈中的Activity全部结束,无Activity可以继续回退时,会销毁此任务栈,并回退到最近一次访问的任务栈的栈顶。

Activity的四种启动模式分别为standardsingleTopsingleTasksingleInstance

有一个模拟浏览器访问主界面MainActivity,包含TextView、Button、EditText等UI组件。请按如下要求编写核心部分代码,组件名自定,应符合见名知意原则:不需要编写全部代码,无需编写其它文件:

1)在MainActivity布局网址文本框、浏览按钮、重置按钮,重置按钮清空已经填入的网址,焦点回到网址文本框里面。(15分)

2)浏览按钮通过intent启动BrowserActivity,在BrowserActivity里面布局一个浏览器显示网址文本框里面的网页内容;(10分)

注意:要求用事件监听器匿名内部类处理两个按钮事件。(5分)

public class MainActivity extends AppCompatActivity {  

    private EditText urlEditText;  

    private Button browseButton, resetButton;  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.activity_main);  

  

        urlEditText = findViewById(R.id.urlEditText);  

        browseButton = findViewById(R.id.browseButton);  

        resetButton = findViewById(R.id.resetButton);  

  

        browseButton.setOnClickListener(new View.OnClickListener() {  

            @Override  

            public void onClick(View v) {  

                Intent intent = new Intent(MainActivity.this, BrowserActivity.class);  

                intent.putExtra("url", urlEditText.getText().toString());  

                // startActivity(intent); 

                startActivityForResult(intent, 1); 

            }  

        });  

  

        resetButton.setOnClickListener(new View.OnClickListener() {  

            @Override  

            public void onClick(View v) {  

                urlEditText.setText("");  

                urlEditText.requestFocus();  

            }  

        });  

    }  

}
public class BrowserActivity extends AppCompatActivity {

    private WebView webView;


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_browser);



        webView = findViewById(R.id.webView);

        String url = getIntent().getStringExtra("url");

        webView.loadUrl(url);

    }

}

第五章:(涉及题型:判断题、单选题、填空题)

1. Android系统在进行文件存储时,内部存储与外部存储的存储位置区别。

内部存储是手机ROM上的一块存储区域,主要用于存储系统以及应用程序的数据,即使手机关机或者退出应用,这些数据也不会丢失。而外部存储则是指SD卡或扩展的外部存储空间,当设备的内置存储空间不足时,可以插入SD卡来扩充存储空间。

2. Android中进行动态申请权限的两个方法:requestPermissions、onRequestPermissionsResult。

3. 几种常见的需要动态申请的危险权限:SD卡读写、读取手机通讯录。

4. SQLite数据库的创建与打开:使用SQLiteOpenHelper类的构造方法。

5. SQLiteOpenHelper类的基本方法:onCreate、onUpgrade、getReadableDatabase、getWritableDatabase。

6. SQLite数据库的CRUD方法:使用SQLiteDatabase工具类。

PersonSQLiteOpenHelper helper = new PersonSQLiteOpenHelper (getApplication());

//获取一个可读写的SQLiteDataBase对象

SQLiteDatabase db = helper.getWritableDatabase();

// 开始数据库的事务

db.beginTransaction();

try {

    //执行转出操作

    db.execSQL("update person set account = account-1000 where name =?",

                                                            new Object[] { "张三" });

    //执行转入操作

    db.execSQL("update information set account = account +1000 where name =?",

                                                             new Object[] { "王五" });

    //标记数据库事务执行成功

    db.setTransactionSuccessful();

}catch (Exception e) {

    Log.i("事务处理失败", e.toString());

} finally {

    db.endTransaction();    //关闭事务

    db.close();              //关闭数据库

}

第六章:(涉及题型:判断题、单选题、填空题)

1. 内容提供者的基本工作原理。

假设B程序需要操作A程序数据库中的数据,一般需要A程序使用ContentProvider暴露数据,才能被其他程序操作。B程序通过ContentResolver操作A程序暴露出来的数据,而A程序会将操作结果返回给ContentResolver,然后ContentResolver再将操作结果返回给B程序。

内容观察者工作原理:使用ContentObserver观察A程序的数据时,首先要在A程序的ContentProvider中调用ContentResolver的notifyChange()方法。调用此方法后,当B程序操作A程序中的数据时,A程序会向“消息中心”发送数据变化的消息,此时C程序会观察到“消息中心”的数据有变化,会触发ContentObserver的onChange()方法。

2. URI的组成结构。

Uri主要有三部分组成,分别是scheme、authority和path。

3. 如何获取内容解析器:getContentResolver方法

4. 如何查询内容提供者的数据:ContentResolver对象所提供的query方法

第七章:(涉及题型:判断题、单选题、填空题)

1. BroadcastReceiver组件的静态注册和动态注册方法。

静态注册的方式是在AndroidManifest.xml文件中进行定义,这种方式注册的广播接收器需要继承自BroadcastReceiver。例如,如果要监听电量变化,就需要在AndroidManifest.xml中进行静态注册。

动态注册则是在程序中使用Context.registerReceiver()方法进行注册。这种方式允许我们在程序运行时动态地注册广播接收器,这在需要根据程序运行状态来开关广播的情况下非常有用。例如,当我们需要监听应用的安装、卸载等事件时,就可以使用动态注册的方式来实现。

另外,当我们发送广播事件时,可以通过Context.sendBroadcast()方法来发送,这个消息会被包含在Intent对象中,并通过Action来指定具体的操作。例如,如果我们希望发送一个标准广播,只需要实例化一个Intent对象,然后调用context的sendBroadcast()方法即可

2. BroadcastReceiver组件的基本方法:onReceive、registerReceiver、sendBroadcast

3. 有序广播与无序广播的区别。

(1) 发送广播时,使用的方法不同。有序广播使用sendOrderedBroadcast()发送广播,而无序广播使用sendBroadcast()方法发送广播。

(2) 广播接收者执行的顺序

  1. 有序广播的接收者是顺序执行的。

有序广播按照广播接收者声明的优先级别被依次接收。当在高级别的广播接收者逻辑执行完毕之后,广播才会继续传递。当优先级相同时,先注册的广播接受者优先执行。

  1. 无序广播是完全异步执行的。

当发送无序广播时,所有监听这个广播的广播接收者都会接收到此广播消息,但接收和执行的顺序不确定。

(3)拦截广播

有序广播的接收者可拦截广播。如果优先级较高的广播接收者将广播终止,那么广播将不再向后传递。而无序广播则不能被拦截。

(4)效率

有序广播的效率比无序广播低。

第八章:(涉及题型:判断题、单选题、填空题、简答题程序设计题

1. Service的两种启动方式的过程及区别。

Service的启动方式分别可以调用startService()、bindService()方法,这两个启动方式的区别如下所示:

  1. 生命周期
  1. startService():使用该方法开启Service时,执行的生命周期方法依次为onCreate()、onStartCommand()、onDestroy()。
  2. bindService():使用该方法开启Service时,执行的生命周期方法依次为:onCreate()、onBind()、onUnbind()、onDestroy()。
  1. 停止服务的方法
  1. startService():调用stopService()方法停止服务。
  2. bindService():调用unbindService()方法停止服务。
  1. 组件的关联
  1. startService():当一个组件通过此方法开启服务时,服务与开启该组件没有关联,即使开启服务的组件被销毁,服务依旧运行。
  2. bindService():当一个组件通过此方法开启服务时,服务会与该组件绑定,组件一旦被销毁,该服务也会被销毁。

2. Service的生命周期方法。

  1. onCreate ():第一次创建服务时执行的方法。
  2. onStartCommand():调用startService()方法启动服务时执行的方法。
  3. onBind():调用bindService()方法启动服务时执行的方法。
  4. onUnbind():调用unBindService()方法断开服务绑定时执行的方法。
  5. onDestory():服务被销毁时执行的方法。

3.本地服务通信的基本原理。

Android本地服务通信的基本步骤:

  1. 创建服务:创建一个继承自Service的类,并在AndroidManifest.xml文件中声明该服务。这个服务将作为本地服务提供给其他组件使用。
  2. 实现Binder:在服务类中创建一个继承自Binder的子类,该子类用于定义服务接口以及提供方法给客户端调用。
  3. 绑定服务:在客户端组件中通过bindService()方法来绑定服务,并传入一个ServiceConnection对象。这个ServiceConnection对象用于监听服务连接状态的变化。
  4. 获取Binder对象:在ServiceConnection的onServiceConnected()方法中获取到Binder对象,客户端就可以通过这个Binder对象来调用服务的方法。
  5. 调用服务方法:客户端可以通过Binder对象调用服务中提供的方法,从而实现与服务的通信和交互。
  6. 解绑服务:在客户端不再需要访问服务时,可以调用unbindService()方法来解绑服务,释放资源。
public class MusicService extends Service {

    private MediaPlayer player;

    public MusicService() {}

    @Override

    public IBinder onBind(Intent intent) {

       return  new MusicControl(); //当服务绑定时,返回服务的代理对象

    }

    @Override

    public void onCreate() {

        super.onCreate();

        player = new MediaPlayer();//创建音乐播放器对象

    }

   

    class MusicControl extends Binder {

            }

    @Override

    public void onDestroy() {

        super.onDestroy();

    }

}
在AndroidManifest.xml中注册服务
<service android:name=".MusicService" />
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static TextView tv_progress, tv_total;

    private MusicService.MusicControl musicControl;

    MyServiceConn conn;

    Intent intent;

    private boolean isUnbind = false;//记录服务是否被解绑



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        init();

    }



    private void init() {

        findViewById(R.id.btn_play).setOnClickListener(this);

        findViewById(R.id.btn_pause).setOnClickListener(this);

        findViewById(R.id.btn_continue_play).setOnClickListener(this);

        findViewById(R.id.btn_exit).setOnClickListener(this);

        intent = new Intent(MainActivity.this, MusicService.class); //创建意图对象

        conn = new MyServiceConn(); //创建服务连接对象

        bindService(intent, conn, BIND_AUTO_CREATE); //绑定服务

        ImageView iv_music = findViewById(R.id.iv_music);

    }



    class MyServiceConn implements ServiceConnection { //用于实现连接服务

        @Override

        public void onServiceConnected(ComponentName name, IBinder service) {

            //获取服务代理对象

            musicControl = (MusicService.MusicControl) service;

        }



        @Override

        public void onServiceDisconnected(ComponentName name) {

        }

    }



    private void unbind(boolean isUnbind) {

        if (!isUnbind) { //判断服务是否被解绑

            musicControl.pausePlay(); //暂停播放音乐

            unbindService(conn); //解绑服务

            stopService(intent); //停止服务

        }

    }



    @Override

    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_play: //播放按钮点击事件

                musicControl.play(); //播放音乐

                animator.start(); //播放动画

                break;

            case R.id.btn_pause: //暂停按钮点击事件

                musicControl.pausePlay(); //暂停播放音乐

                animator.pause(); //暂停播放动画

                break;

            case R.id.btn_continue_play: //继续播放按钮点击事件

                musicControl.continuePlay(); //继续播放音乐

                animator.start(); //播放动画

                break;

            case R.id.btn_exit: //退出按钮点击事件

                unbind(isUnbind); //解绑服务绑定

                isUnbind = true; //完成解绑服务

                finish(); //关闭音乐播放界面

                break;

        }

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        unbind(isUnbind); //解绑服务

    }

}

4. Android系统的四大核心组件名称、作用以及在清单文件中的注册方式。

Activity:负责用户交互的最主要组件,一个Activity表示一个可视化用户界面,除非不需要任何用户界面,否则Android应用程序至少包含一个Activity。

Service:用于提供服务,执行一些持续性的,耗时的且无需用户界面交互的操作。

BroadcastReceive:一种全局监听器,用于接收来自系统和应用程序的广播。

ContentProvider:一种共享的持久数据存储机制,是在应用程序之间共享数据时的首选方案。

注册主 Activity 时, 还需要内嵌<intent-filter>、<action>和<category>标签,以此说明 该 Activity 为 Android 应用程序的入口

<activity

    android:name="prg_packname.MainActivity"

    android:label="@string/app_name">

    <intent-filter>

        <action android:name="android.intent.action.MAIN"A>

        <category android:name="android.intent.category.LAUNCHER">

    </intent-filter>

</activity>

第九章:(涉及题型:判断题、单选题、填空题)

1. HttpURLConnection类的作用及两种不同的发送HTTP请求的方式。

HttpURLConnectionJava的标准类,它继承自URLConnection并被用于发送HTTP请求以及处理服务器的响应。这个类提供了一些特定的方法,如获取服务器响应代码、获取服务器响应消息和设置请求方法等。

HttpURLConnection主要支持以下两种发送HTTP请求的方式:GET和POSTGET请求主要用于获取资源,而POST请求则通常用于提交数据到服务器。

2. JSON数据的两种表示结构:对象结构和数组结构

3. Android SDK提供的两种不同的解析JSON数据的类:JSONObjectJSONArray

第十章:(涉及题型:判断题、单选题、填空题)

1. 利用Bitmap类与BitmapFactory类创建位图的区别。

Bitmap是一张位图,代表一个图像,可以被用来存储和操作图像的像素数据。开发者可以通过Bitmap类提供的方法来获取、设置和修改图像的像素值,实现对图像的各种操作。BitmapFactory则是一个用于创建Bitmap对象的工厂类,可以从不同来源(如文件、网络等)解码图像数据并生成对应的Bitmap对象。

2. 三种不同的动画类型名称与基本特点:补间动画、逐帧动画、属性动画。

  1. 补间动画是Flash中常见的动画形式,它通过在关键帧之间插入中间帧来实现动画效果。补间动画适用于实现基本形状、位置、大小、颜色等属性的变化。
  2. 逐帧动画是通过在每一帧上绘制不同的图像来创建动画效果。它适用于实现复杂的变化和过渡,例如人物动作、场景变化等。逐帧动画需要手动绘制每一帧,因此制作过程相对繁琐。
  3. 属性动画是Android开发中常用的动画形式,它通过改变对象的属性值来实现动画效果。属性动画适用于实现位置、大小、透明度、旋转等属性的变化。属性动画可以通过代码动态设置属性值,从而实现更加灵活和动态的动画效果。

第十一章:(涉及题型:判断题、单选题、填空题)

1. 使用MediaPlayer类播放音频的基本方法:setDataSource、prepare、start、pause、stop

2. 使用MediaPlayer类播放视频与播放音频在使用上的区别。

  1. 资源格式:音频和视频的资源格式是不同的。音频文件通常是.mp3、.wav、.aac等格式,而视频文件通常是.mp4、.avi、.flv等格式。因此,在使用MediaPlayer类播放这些资源时,需要根据不同的格式设置相应的媒体类型。
  2. 播放方式:音频和视频的播放方式也有所不同。音频通常可以通过MediaPlayer类的play()方法进行播放,而视频则需要通过SurfaceView或者VideoView进行播放。这是因为视频播放需要更大的带宽和更高的解码能力,因此需要使用更复杂的方式进行播放。
  3. 显示效果:视频和音频的显示效果也有所不同。音频只有声音,而视频则包括声音和图像。因此,在使用MediaPlayer类播放视频时,需要设置相应的显示效果,如缩放、旋转等。
  4. 错误处理:在使用MediaPlayer类播放音频和视频时,错误处理的方式也有所不同。音频播放的错误通常可以通过重试或者使用备用资源等方式进行解决,而视频播放的错误则可能需要更复杂的错误处理机制,如重新下载或者切换到其他源等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值