Android开发从零开始笔记

1.开发环境搭建:(1)安装JDK  (2)安装Eclipse   (3)安装 ANDROID SDK (环境变量配置:新建环境变量,路径指向sdk所在文件夹,然后在path中添加该环境变量。检验是否配置成功:console下输入adb。) (4)eclipse>>help>>install new software>>add 填入name和location,location为ADT的物理路径。Eclipse配置:window>>preferences>>Android  SDK Location 选择SDK路径。 OK
2.android SDK目录介绍:(1)addones:android开发所需的第三方文件。(2)docs:android的文档,包括开发指南,API等。(3)extras:附件文档。(5)platforms:一系列安卓平台 。 (6) platform-tools:开发工具,在平台更新时可能会更新。(7)samples:例子。(8)tools:独立于安卓平台的开发工具。 
3.模拟器:(1)创建模拟器:方式一:console 运行 SDK tools目录下的emulator.exe。方式二:eclipse Android Virtual Device and SDK Manager>>在Virtual Devices选项卡中,选择new新建一个虚拟设备>>配置虚拟设备的信息:Name:虚拟设备名 Target:版本 SD Card:设置SD卡大小   skin:模拟器大小。 >>配置好虚拟设备后 单击start...运行虚拟设备。(2)模拟器中安装软件:把要安装的apk放置于SDK tools目录下,打开控制台,切换到SDK tools目录下 然后运行:adb install  xxx.apk。(3)卸载软件:方式一:在模拟器中 设置>>应用程序>>管理应用程序>>找到要卸载的软件选中,单击>>强行停止 ,卸载。方式二:打开控制台,切换到SDK tools目录下 然后运行:adb uninstall zzz.xxx.apk。(卸载时为完整名称,包名.文件名)
4.Activity:每个Activity对象是个单独实体,应用程序中可能会有多个Activity,但每次只能有一个展现在用户面前。OnCreate() 将会在Activity运行时,被android系统调用,用开处理初始化信息,如构建UI界面、加载资源文件等。
5.TextView创建的两种方式:(1)在程序中创建TextView对象。(2)在xml布局文件中使用。
6.TextView属性:(1)android:textSize设置字体大小,推荐使用sp作单位。设置宽度或高度 属性,推荐使用dp作单位。dp与sp介绍:dp就是dip。设置表示长度、高度等属性时,可以使用dp或sp,但如果设置字体需要使用sp。dp与密度无关,sp除了与密度无关还与scanle无关  。使用dp或sp系统会根据屏幕密度的变化自动转换。其他单位含义:px:表示屏幕实际的像素。in:表示英寸,是屏幕的物理尺寸。形容手机屏幕大小, 表示 屏幕对角线的长度, 3.2英寸手机屏幕大小为:3.2*2.54=8.12厘米。 mm:表示毫米,是屏幕的物理尺寸。pt:表示一个点,是屏幕的物理尺寸,大小为一英寸的1/72。(2)设置字体颜色,方式一:andorid:textColor设置字体颜色。 方式二:建立一个TextView对象,调用setText(Html.fromHtml("运用HTML方法设置字体颜色")) 。方式三:建立SpannableStringBuilder对象,调用setSpan方法。(3)设置超级链接,android:autoLink:设置是否当文本为URL链接/email/电话/map时,文本显示为可单击的链接。可选值:none/ web /email/phone/map/all。(4)跑马灯效果:android:ellipsize设置当文字过长时,控件如何显示.有如下值:start:省略号显示在开头,end:省略号显示在结尾。middle:省略号显示在中间.marquee:以跑马灯的方式显示(动画横向移动)。android:marqueeRepeatLimit,在ellipsize指定marquee的情况下设置重复滚动的次数.当设置为marquee_forever时,表示无限次。android:focusableInTouchMode:是否在触摸模式下获得焦点。android:focusable事件是否能够获得焦点。
7.EditText属性:(1)android:maxLength限制输入框中的字符数。(2)android:singleLine属性,控制是否以多行文本显示。(3)限制输入信息:android:inputType。(4)设置提示信息:android:hint。(5)在EditText中显示图片:android:drawableLeft。(6)设置圆角:android:bakground=“@drawable/shape”()。
8.Button:给Button添加事件处理的三种方式:第一种:实现OnClickListener接口,复写OnClick方法。第二种:使用匿名内部类。第三种:private OnClickListener listener=new OnClickListener() {    
   public void onClick(View v) {
    Button button=(Button)v;
    switch(button.getId())
    {
     case R.id.button1:
      Toast.makeText(MainActivity.this, "you have clicked the Button", Toast.LENGTH_LONG).show();
      break;
     case R.id.button2:
      System.out.println("you clincked the button2");
    }     
   }
  };
9.Intent:一个Intent就是一次对将要执行的操作的抽象描述。
10.Log类:(1)Log.v(String tag,String msg)。 (2)Log.d(String tag,String msg)。(3)Log.i(String tag,String msg)。
(4)Log.w(String tag,String msg)。(5)Log.e(String tag,String msg)。
11. Activity生命周期相关的方法:protected void onCreate(Bundle savedInstanceState);protected void onStart();
protected void onRestart();protected void onResume();protected void onPause();protected void onstop();protected void onDestory();


保存Activity状态:OnSaveInstanceState().
12.andorid theme : android:theme="@android style/Theme.Dialog";android:theme="@android style/Theme.NoTitleBar";android:theme="@android style/Theme.NoTitleBar.FullScreen";
13.布局:(1)LinearLayout:线性布局,可以分为水平线性布局和垂直线性布局两种。通过android:orientation可以设置线性布局的方向。android:gravity用于控制布局中,控件的对齐方式,如果是没有子控件的控件设置此属性,表示其内容的对齐方式。若果是有子控件的控件设置此属性,表示其子控件的对齐方式。android:layout_weight,控制各个部件在布局中的相对大小。layout_weight属性是一个非负整数值,线性布局会根据该控件layout_weight值与其所处布局中所有控件layout_weight值之和的比值为该控件分配占用的区域。(2)AbsoluteLayout:指定子控件的xy精确坐标的布局。绝对布局缺乏灵活性,在没有绝对定位的情况下比其他类型布局更难维护。android:layout_x指定x坐标。android:layout_y指定y坐标。(3)FrameLayout:框架布局,所有添加到这个布局中的视图都以层叠的方式显示,第一个添加的组件放在最底层,最后添加到框架中的视图显示在最上面,上一层的会覆盖下一层的控件。layout_gravity和gravity作用对象时不一样的。(4)RelativeLayout:相对布局,在这个容器的内部的子元素们可以使用彼此之间的相对位置或者和容器间的相对位置来进行定位。(注:不能在RelativeLayout容器本身和它的子元素之间产生循环依赖。)与RelativeLayout相关的布局属性:android:layout_above,将该控件置于给定ID的控件之上。android:layout_below,将该控件置于给定ID的控件之下。android:layout_toLeftOf,将该控件置于给定ID的控件之左。android:layout_toRightOf,将该控件置于给定ID的控件之右。android:layout_alignBaseline:该控件基线对齐给定ID的基线;android:layout_alignBottom:该控件与给定ID的控件底部对齐;android:layout_alignLeft:该控件与给定ID的控件左对齐;android:layout_alignRight:该控件与给定ID的控件右对齐; android:layout_alignTop: 该控件与给定ID的控件顶对齐;android:layout_alignParaentRight如果为true,该控件位于父控件的右部。android:layout_alignParaentLeft如果为true,该控件位于父控件的左部。android:layout_alignParaentTop如果为true,该控件位于父控件的顶部。android:layout_alignParaenBottomt如果为true,该控件位于父控件的底部。andorid:layout_centerHorizontal如果为true,该控件将被置于水平方向的中央。andorid:layout_centerInParent如果为true,该控件将被置于父控件水平方向和垂直方向的中央。andorid:layout_centerVertical如果为true,该控件将被置于垂直方向的中央。(5)TableLayout:表格布局是一个ViewGroup以表格显示它的子视图(View)元素,即行和列标示一个视图的位置.TableLayout常用属性:android:collapseColumns:隐藏指定的列。android:shrinksColumns:收缩指定的列以适合屏幕,不会挤出屏幕。android:stretchColumns:尽量把指定的列填充空白部分。android:layout_column控件在TableRow中所处的列。android:layout_span:该控件所跨越的列数。
14.fill_parent和wrap_content:wrap_content:表示大小刚好足够显示当前控件里的内容。fill_parentmatch_parent:
Android中fill_parent和match_parent(从Android2.2)是一样的。  为了兼容低版本,建议使用fill_parent  设置布局/控件为fill_parent将强制性让它布满整个屏幕或填满父控件的空白。
15.程序调试:(1)Log日志的输出:(2)单元测试:第一步:在清单文件文件中添加信息:
<application>
        <uses-library android:name="android test runnner" />
        <activity></activity>
</application>
<instrumentation 
    android:name="android.test.InstrumentationTestRunner"
    android:targetPackage="szy.android.activity"
    android:label="Testing"
/>
第二步:编写单元测试方法
public class TestCase extends AndroidTestCase
{   }
(3)Debug:Step Into(F5)  Step Over(F6)   Step Return(F6)  Run to Line (Ctrl+R)
16.Service:(1)什么是Service:A Service  is an application component that can perform long-running operations in the background and does not provide a user interface.(2) 使用Service方式:方式一:startService():调用者和服务之间没有联系,即使调用者退出了,服务仍然进行 [onCreate()-->startService()-onDestory()] 。方式二:bindService():调用者和服务绑在一起,调用者一旦退出服务也就终止[onCreate()-->onBind()-->onUnbind()-->onDestory()] 。(3)通过startService使用Service:Step1:编写类继承Service或其子类 。Step2:复写方法 onStartCommand() 、onBind() 、onCreate() 、onDestroy() 。Step3:在manifest文件中声服务 <service android:name=".Service" /> 。Step4:启动服务。Step5:关闭服务。
(4)三个常量:START_STICKY:当服务进程在运行时被杀死,系统将会把它值为started状态,但是并不保存其传递的Intent对象 ;START_NOT_STICKY:当服务进程在运行时被杀死,并且没有新的Intent对象传递过来,统将会把它值为started状态,但是并不会再次创建进程,直到startService(Intent)方法被调用; START_REDELIVER_INTENT:当服务进程在运行时被杀死,它将会间隔一段时间后重新被创建,并且最后一个传递的Intent对象将会再次传递过来。 (5)什么是BindService:Bound service 允许其它的组件(比如Activities)绑定到这个Service上,可以发送请求,也可以接受请求,甚至进行进程间的通话。Bound service 仅仅在服务于其它组件时存在,不能独自无限期的在后台运行。 (6)创建BindService:当创建一个能提供绑定功能的服务时,必须提供一个IBinder对象,客户端能使用这个对象与服务进行交互。在Android中有三种方式定义方式: 扩展Binder类,使用Messenger、使用AIDL (Android Interface Definition Language) 。通过Binder类创建Bound Service:步骤: a.在Service类中,创建一个Binder实例 包含客户端能调用的公共方法 返回当前服务对象。 b.在onBind()方法中返回Binder实例。 c.在客户端,从onServiceConnected()方法中获得Binder实例,

(7)IntentService使用:IntentService是Service类的子类,用来处理异步请求。客户端通过startService(Intent)方法传递请求给IntentService,IntentService通过worker thread处理每个Intent对象,执行完所有工作后自动停止Service。 
IntentService执行如下操作:创建一个与应用程序主线程分开worker thread用来处理所有通过传递过来的Intent请求 ;创建一个work queue,一次只传递一个intent到onHandleIntent()方法中,从而不用担心多线程带来的问题; 当处理完所有请求后自动停止服务,而不需要我们自己调用stopSelf()方法; 默认实现了onBind()方法,返回值为null ;默认实现了onStartCommand()方法,这个方法将会把我们的intent放到work queue中,然后在onHandleIntent()中执行。
17.消息处理:(1)消息队列(MessageQueue):存放消息的地方,按照FIFO规则执行,每一个线程只可以拥有一个MessageQueue,在创建一个Looper对象时,会创建一个MessageQueue对象。(2)消息对象(Message):MessageQueue中存放的对象。一个MessageQueue中可以包含多个Message对象。可以通过Message.obtain()或者Handler.obtainMessage()获取Message对象。获取Message对象时,先从消息池中看有没有可用的Message实例,如果存在则直接取出返回这个实例,如果不存在则用给定的参数创建一个一个Message对象。调用removeMessage()时,将Message从MessageQueue中删除,同时放入到消息池中。(3)Looper:操作MessageQueue。一个Looper对应一个MessageQueue。通过调用Looper.myLooper()可以获得当前线程的Looper对象。Looper从MessageQueue中取出Message然后,交由Handler的handleMessage()进行处理。处理完成后,调用Message.recycle()将其放入消息池中。
(4)Handler:消息的处理者。handler负责将需要传递的信息封装成 Message对象,然后调用sendMessage()方法将消息放入MessageQueue中。当MessageQueue循环到该Message,调用相应的handler对象的handleMessage()方法对其进行处理。Handler都可以共享同一Looper和MessageQueue。
18.Status Bar Notifications:status bar notification添加一个icon到系统的状态栏中(可选择是否有文本信息),添加一段信息到"Notifications" 窗口中。 当在后台运行的服务需要与用户进行交互时我们可以使用status bar notification。 创建notification可以通过Notification类或者NotificationManager类。
19.广播事件:(1)广播接收器(BroadcaseReceiver),它和事件处理机制类似,只不过事件处理机制是程序组件级别,而广播事件处理机制是系统级别。 (2)使用BroadcaseReceiver的步骤:i:编写类继承BroadcaseReceiver,复写onReceiver()方法 。ii: 在AndroidManifest.xml文件中注册BroadcaseReceiver 。iii:构建Intent对象 。iv:调用sendBroadcase()方法发送广播。(3)BroadcaseReceiver的生命周期:BroadcastReceiver对象仅在调用onReceive()方法时有效,当该方法执行完毕后,系统认为销毁该对象。(4)注册Broadcast Receiver的方法:I:在AndroidManifest.xml文件中进行注册。II:在应用程序的代码中进行注册。在应用程序的代码中进行注册:i:注册BroadcastReceiver: registerReceiver()。ii: 取消注册BroadcastReceiver :unregisterReceiver() .
20.数据存储: (1)Android的数据存储方式:SQLite数据库、文件、Shared Preferences、内容提供者(Content Providers)、网络。(2)SQLite数据库:是一款轻型数据库,它的设计目标是嵌入式的,它占用资源低、支持主流操作系统、能与多种程序语言结合、处理速度快。i:SQLite数据类型:一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断。SQLite具有以下五种数据类型: 1).NULL:空值。 2).INTEGER:带符号的整型,具体取决有存入数字的范围大小。 3).REAL:浮点数字,存储为8-byte IEEE浮点数。 4).TEXT:字符串文本。 5).BLOB:二进制对象。(3)SQLiteOpenHelper类:A helper class to manage database creation and version management. 方法:synchronized void close() 、 synchronized SQLiteDatabase getReadableDatabase() 、 synchronized SQLiteDatabase getWritableDatabase() 、 abstract void onCreate(SQLiteDatabase db) 、 void onOpen(SQLiteDatabase db) 、 abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
(4)将数据存储到文件上:i.openFileOutput (String name, int mode)   name:文件的名称,不能包含分隔符"/",如果文件不存在,Android会自动创建它。创建的文件保存在/data/data/<package_name>/files目录下。 mode:操作模式。 ii.openFileInput (String name) 。iii:Mode:i)MODE_APPEND  如果文件中已经存在内容,则在内容末尾追加。ii): MODE_PRIVATE  文件仅能被该程序访问。iii): MODE_WORLD_READABLE  文件允许被其它应用程序读。iv): MODE_WORLD_WRITEABLE  文件允许被其它应用程序写 。v):MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE  文件允许被其它应用程序读写 。
(5)Shared Preferences保存配置信息到文件。
21.SAX解析XML文件:(1)Android中解析XML文件的方法:i:SAX:Simple API for XML。ii: DOM:Document Object Model 。iii:pull 。(2)SAX:SAX是一个解析速度快并且占用内存少的XML解析器。SAX解析XML文件采用的是事件驱动,也就是它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到字符是否符合XML语法中的某部分,如果符合则出发事件。所谓的事件其实就是一些回调函数,这些方法定义在ContentHandler接口中。 (3) ContentHandler接口常用方法:i:startDocument()  当遇到文档的开头时候,调用这个方法,可以在该方法中进行预处理工作。    ii: endDocument() 当文档结束的时候,调用这个方法,可以在该方法中进行善后工作。    iii: startElement() 当读到一个开始标签的时候,会触发该方法 。    iv:endElement() 当遇到结束标签的时候,会调用该方法。    v: characters() 该方法用来处理在XML文件中读到的内容 。(4)使用SAX读取XML文件:使用SAX读取XML文件时需创建一个类实现ContentHandler接口。此外可以编写一个类继承DefaultHandler类,然后重新里面的方法: SAXParserFactory spf=SAXParserFactory.newInstance();      
   SAXParser saxParser=spf.newSAXParser();//创建解析器     
    XMLContentHandler handler=new XMLContentHandler();
    saxParser.parse(inStream, handler);
Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件。对于特别大的文档,解析和加载整个文档可能很慢且很耗资源 。Pull解析和Sax解析很相似,都是轻量级的解析,在Android的内核中已经嵌入了Pull,所以我们不需要再添加第三方jar包来支持Pull。Pull解析和Sax解析不一样的地方有 i):pull读取xml文件后触发相应的事件调用方法返回的是数字。ii):pull可以在程序中控制想解析到哪里就可以停止解析。
22.Content Providers: (1)Content Providers 是所有应用程序之间数据存储和检索的一个桥梁,作用是使得各个应用程序之间实现数据共享。它是应用程序间共享数据的唯一方法。每个content provider有一个公有URI, 该URI用于识别它所代表的数据集合。 所有的content  provider的URI以字符串"content://"开始.(2)Content Provider使用步骤:i.定义一个继承 ContentProvider的类。ii.声明一个Uri类型的常量CONTENT_URI 。iii.实现query()、insert()、update()、delete()、  getType()、onCreate()方法。iv.在AndroidManifest.xml文件中进行声明 。
23.Http请求: (1)GET请求方式:GET方式是通过把参数键值对附加在url后面来传递的。在服务器端可以直接读取,效率较高,但缺乏安全性,也无法来处理复杂的数据,长度有限制。主要用于传递简单的参数。 (2)POST请求方式:POST方式:就传输方式将参数会被打包在http报头中传输,可以是二进制的。便于传送较大一些的数据,同时因为不暴露数据在浏览器的地址栏中,安全性相对较高,但这样的处理效率会受到影响。 (3)Android实现http请求的方式:i:HttpURLConnection方式。ii:HttpClient方式。
24.控件: (1)单选按钮:RadioButton,需要放在RadioGroup中,事件处理:OnCheckedChangeListern,复写onCheckedChanged(CompoundButton buttonView,boolean isChecked)方法。(2)复选按钮:CheckBox,事件处理:OnCheckedChangeListern,复写onCheckedChanged(CompoundButton buttonView,boolean isChecked)方法。(3)日期、时间:DatePicker、DatepickerDialog、TimePicker、TimePickerDialog。事件处理:init(int year,int monthOfYear,int dayOfMonth,OnDateChnagedListener onDateChnagedListener).(注:年份和月份是从1开始月份从0开始的,为了准确表达月份可对月份进行+1处理)。(4)ListView:A view that shows items in a vertically scrolling list。ListAdapter: is the bridge between a ListView and the data that backs the list.(5)GridView:A view that shows items in two-dimensional scrolling grid. The items in the grid come from the ListAdapter associated with this view.(6)TableWidget:TabWidget通过多个标签切换显示不同的内容。TabHost,是一个存放多个Tab标签的容器。每个Tab都可以对应自己的布局。 (7)Spinner、Auto Complete:A view that displays one child at a time and lets the user pick among them. The items in the Spinner come from the Adapter associated with this view.(8)Web View:A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. (9)Dialog:A dialog is usually a small window that appears in front of the current Activity. The underlying Activity loses focus and the dialog accepts all user interaction. Dialogs are normally used for notifications that should interupt the user and to perform short tasks that directly relate to the application in progress . Direct Subclasses:i)AlertDialog:A subclass of Dialog that can display one, two or three buttons. ii): CharacterPickerDialog:Dialog for choosing accented characters related to a base character.   Indirect Subclasses:i):DatePickerDialog:A simple dialog containing an DatePicker. ii): ProgressDialog : A dialog showing a progress indicator and an optional text message or view.  
iii):TimePickerDialog A dialog that prompts the user for the time of day using a TimePicker. Methods: onCreateDialog(int), onPrepareDialog(int, Dialog), showDialog(int), and dismissDialog(int).(10)通知的三种方式:i:Toast Notification。ii: Dialog Notification 。iii:Status Bar Notification。创建Status Bar Notifications:i):Notification:定义Status Bar的属性,比如图标、显示文本等。ii):NotificationManager:NotificationManager是Android系统服务,用来执行和控制所有的Notifications.    (11)AppWidgets:Android allows applications to publish views to be embedded in other applications. These views are called widgets, and are published by "AppWidget providers." The component that can contain widgets is called a "AppWidget host."     Classes: i ) :AppWidgetManager Updates AppWidget state; gets information about installed AppWidget providers and other AppWidget related state.   ii):AppWidgetProvider A convenience class to aid in implementing an AppWidget provider.   PendingIntent和Intent的区别:Intent 表示一个目的,第一个参数表示所在类,第二个参数表示目标类 。PendingIntent即是一个Intent的描述。 PendingIntent就是一个Intent的描述,我们可以把这个描述交给别的程序,别的程序根据这个描述在后面的别的时间做你安排做的事情。换种说法Intent字面意思是意图,即我们的目的,我们想要做的事情,在Activity中,我们可以立即执行它,PendingIntent相当于对Intent执行了包装,我们不一定要马上执行它,我们将其包装后,传递给其他Activity或Application。这时,获取到PendingIntent的Application 能够根据里面的Intent来得知发出者的意图,选择拦击或者继续传递或者执行。     PendingIntent的四个常量:i):int FLAG_CANCEL_CURRENT:Flag for use with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int): if the described PendingIntent already exists, the current one is canceled before generating a new one.
ii):int FLAG_NO_CREATE:Flag for use with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int): if the described PendingIntent does not already exist, then simply return null instead of creating it.
iii):int FLAG_ONE_SHOT :Flag for use with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int): this PendingIntent can only be used once.
iv):int FLAG_UPDATE_CURRENT Flag for use with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int): if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent.关于四个常量的补充说明:4个flag中最经常使用的是FLAG_UPDATE_CURRENT,因为描述的Intent有更新的时候需要用到这个flag去更新你的描述(确切的说是更新extra data),否则组件在下次事件发生或时间到达的时候extras永远是第一次Intent的extras;使用FLAG_CANCEL_CURRENT也能做到更新extras,只不过是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的区别在于能否新new一个Intent,FLAG_CANCEL_CURRENT能够新new一个Intent,而FLAG_UPDATE_CURRENT则不能,只能使用第一次的Intent。
25.Menu: i):Options menus    ii):Sub menus:Subclass of Menu for sub menus.     iii):Context menus:Extension of Menu for context menus providing functionality to modify the header of the context menu. 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值