Android开发

activity的管理:

复习:定义一个activity
—— 创建一个Activity子类
——重写Activity中的onCreate方法
—— 在AndroidManifest.xml中的Activity进行注册

启动一个Activity

——创建Intent意图对象(可以理解成一个封装对象

——调用setClass设置要启动哪个Activity
——调用startActivity进行跳转

BackStack回退栈

1、先进后出 2、方便记录后维护

Menu分类:

选项菜单(OptionMenu)

上下文菜单(ContextMenu)

弹出菜单(PopupMenu)

OptionMenu:

showAsAction属性值:always:直接在标题显示
never:不显示
withText:控制图标贺文本一起显示
ifRoot:有空间就显示
  //创建OptionMenu
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //加载资源文件
        getMenuInflater ().inflate ( R.menu.option,menu );
        return true;
    }
    //OptionMenu添加事件方法
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId ()){
            case R.id.menu1:
                Toast.makeText ( this, "保存", Toast.LENGTH_SHORT ).show ();
                break;
            case R.id.menu2:
                Toast.makeText ( this, "设置", Toast.LENGTH_SHORT ).show ();
                break;
        }
        return super.onOptionsItemSelected ( item );
    }

ContextMenu:

长按某个view不放,就会在屏幕中间弹出ContextMeun
        //contextMenu:演示ContextMenu
        //4、为按钮设置上下操作模式,要进入上下操作模式就要先创建 ActionMode.Callback对象
        //①实现ActionMode CallBack
        //②在view的长按事件中去启动上下文操作模式
        
 //先创建 ActionMode.Callback对象
            ActionMode.Callback cb=new ActionMode.Callback () {
        //创建,在启动上下文操作模式(startActionMode(Callback))是调用
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            Log.i ( "TAG","创建" );
            getMenuInflater ().inflate ( R.menu.contextmenu,menu );
            return true;
        }
        //在创建方法后进行调用
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            Log.i ( "TAG","准备" );
            return false;
        }
        //单击按钮时
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId ()){
                case R.id.up_name:
                    Toast.makeText ( mode1_activity.this, "重命名", Toast.LENGTH_SHORT ).show ();
                    break;
                case R.id.del:
                    Toast.makeText ( mode1_activity.this, "删除", Toast.LENGTH_SHORT ).show ();
                    break;
            }
            return true;
        }
        //上下文操作模式结束时被调用
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            Log.i ( "TAG","结束" );

        }
    };
//调用
        findViewById ( R.id.contextMenu ).setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                startActionMode ( cb );
            }
        } );

//如果不进入上下本模式
//1、注册
        registerForContextMenu ( findViewById ( R.id.contextMenu ) );
 //2、创建 覆盖
 //2、创建 覆盖onCreateContextMenu
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        getMenuInflater ().inflate ( R.menu.contextmenu,menu );//
        super.onCreateContextMenu ( menu, v, menuInfo );
    }
//3、菜单项的操作onContextItemSelected
            @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId ()){
            case R.id.up_name:
                Toast.makeText ( this, "重命名", Toast.LENGTH_SHORT ).show ();
                break;
            case R.id.del:
                Toast.makeText ( this, "删除", Toast.LENGTH_SHORT ).show ();
                break;
        }
        return super.onContextItemSelected ( item );
    }

PopupMenu:

按一下某个view,一般会在下方弹出
      //popupMenu:演示PopupMenu
        final Button button=findViewById ( R.id.popupMenu );
        button.setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                // ①实例化PopupMenu对象(参数2:被锚定的view)
                PopupMenu popupMenu=new PopupMenu ( mode1_activity.this, button);
                // ②加载菜单资源:利用MenuInflater将Menu资源加载到PopupMenu.getMenu(),所返回的Menu对象中
                //将R.meun.contextmenu对于的菜单资源加载到弹出式菜单中
                popupMenu.getMenuInflater ().inflate ( R.menu.popupmenu,popupMenu.getMenu () );
                // ③为PopupMenu设置点击监听器
                popupMenu.setOnMenuItemClickListener ( new PopupMenu.OnMenuItemClickListener () {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getItemId ()){
                            case R.id.copy:
                                Toast.makeText ( mode1_activity.this, "复制", Toast.LENGTH_SHORT ).show ();
                                break;
                            case R.id.del1:
                                Toast.makeText ( mode1_activity.this, "删除", Toast.LENGTH_SHORT ).show ();
                                break;
                        }
                        return true;
                    }
                } );
                // ④千万不要忘show
                popupMenu.show ();
            }
        } );

java编写menu:

加粗样式

对话框

1、普通对话框(一):

利用AlterDialog中的构建器(Builder)来完成。
通过方法有:setTitle、setMessage、create、show
三个事件:
——setPositiveButton:确定
——setNegativeButton:否
——setNeutralButton:取消

    private void showdialog1() {
        /*
        * AlertDialog
        * AlerDialog的构造方法是被修饰为protected
        * 因此包外是无法使用的,所以我们利用构建器(Builder)
        * */
        AlertDialog.Builder builder=new AlertDialog.Builder ( this );
//        设置对话框标题
        builder.setTitle ( "提示" );
//        设置内容
        builder.setMessage ( "你是否要退出程序!" );
//         设置按钮
        builder.setPositiveButton ( "确定", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                activity_Dialog.this.finish ();
            }
        } );
        builder.setNegativeButton ("取消",null  );
//        builder.setNeutralButton (  );
//        builder.create ();
        builder.show ();
    }

2、普通对话框(二):

用到几个常量:BUTTON_POSITIVE、BUTTON_NEGATIVE、BUTTON_NEUTRAL

//    打分式对话框
    private void showdialog2() {
        AlertDialog dialog=new AlertDialog.Builder (this).create ();
        dialog.setTitle ( "评价" );
        dialog.setMessage ( "请为本次服务打分!" );
        //BUTTON_POSITIVE:常量
        dialog.setButton ( DialogInterface.BUTTON_POSITIVE, "5分", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText ( activity_Dialog.this, "您选择了5分", Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.setButton ( DialogInterface.BUTTON_NEGATIVE, "3分", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText ( activity_Dialog.this, "您选择了3分", Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.setButton ( DialogInterface.BUTTON_NEUTRAL, "1分", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText ( activity_Dialog.this, "您选择了1分", Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.show ();
    }

3、列表对话框:

有一个方法:setItems

//    列表对话框
    private void showdialog3() {
        final String[] strings={"我是1","我是2","我是3","我是4"};
        AlertDialog.Builder dialog=new AlertDialog.Builder ( this );
        dialog.setTitle ( "请选择" );
        dialog.setItems ( strings, new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                /*
                which:strings的索引从0开始
                * */
                Toast.makeText ( activity_Dialog.this, strings[which], Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.show ();
    }

4、单选对话框:

方法:setSingleChoiceItems

//  单选对话框
    int s = 0;
    private void showdialog4() {
        final String[] strings={"赵丽颖","蓝洁瑛","范冰冰","王源","唐嫣","杨幂"};
        AlertDialog.Builder dialog=new AlertDialog.Builder ( this );
        dialog.setTitle ( "你喜欢谁?" );
        /*
        * strings:数组
        * 0:是默认选中的
        * */
        dialog.setSingleChoiceItems ( strings, 0, new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                s =which;
            }
        } );
        dialog.setPositiveButton ( "确定", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText ( activity_Dialog.this, strings[str[0]],Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.show ();
    }

5、多选对话框:

方法:setMultiChoiceItems

//  多选对话框
    private void showdialog5() {
        final String[] strings={"赵丽颖","蓝洁瑛","范冰冰","王源","唐嫣","杨幂"};
        final boolean[] start={true,true,false,false,false,false};
        AlertDialog.Builder dialog=new AlertDialog.Builder ( this );
        dialog.setTitle ( "你选择那些!" );
        dialog.setMultiChoiceItems ( strings, start, new DialogInterface.OnMultiChoiceClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                /*
                 * dialog:对象控件
                 * which:索引
                 * isChecked:状态
                 * 当改变复选框状态时触发
                 * */
                start[which]=isChecked;
            }
        } );
        dialog.setPositiveButton ( "确定", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String mes="";
                for (int i=0;i<strings.length;i++) {
                    if (start[i]){
                        mes+=strings[i]+"、";
                    }
                }
                Toast.makeText ( activity_Dialog.this, mes, Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.show ();
    }

6、等待对话框(progressDialog):

方法:setCancelable

//  等待对话框
    private void showdialog6() {
        ProgressDialog progressDialog=new ProgressDialog ( this );
        progressDialog.setTitle ( "请等待" );
        progressDialog.setMessage ( "正在加载..." );
        progressDialog.setCancelable ( false );//默认为true(是否可返回)
        progressDialog.show ();
        progressDialog.dismiss ();//关闭对话框
    }

7、进度条对话框

方法:setIndeterminate、setProgressStyle(ProgressDialog.STYLE.HORIZONTAL)

//  进度条对话框
    private void showdialog7() {
        final ProgressDialog progressDialog=new ProgressDialog ( this );
        progressDialog.setTitle ( "下载中" );
        progressDialog.setMessage ( "正在加载..." );
        progressDialog.setIndeterminate ( false );//默认:false,设置为模糊的
//       设置样式
        progressDialog.setProgressStyle ( ProgressDialog.STYLE_HORIZONTAL );
        progressDialog.show ();
//        progressDialog.setProgress ( 30 );
        new Thread ( ){
            @Override
            public void run() {
                for (int i=0;i<=100;i++){
                    progressDialog.setProgress ( i );
                    try {
                        Thread.sleep ( 40 );
                    } catch (InterruptedException e) {
                        e.printStackTrace ();
                    }
                }
                progressDialog.dismiss ();
            }
        }.start ();
    }

8、输入对话框

方法:setView

    //  输入对话框
    private void showdialog8() {
        final EditText edit=new EditText (  this);
        AlertDialog.Builder dialog=new AlertDialog.Builder ( this );
        dialog.setTitle ( "输入对话框" );
        dialog.setView ( edit);//这里可以用布局文件
        dialog.setPositiveButton ( "确定", new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText ( activity_Dialog.this, "输入:"+edit.getText ().toString (), Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.show ();
    }

9、自定义对话框

布局

                /*
                *自定义对话框
                * 1、自定义一个类,继承Dialog类
                * 2、创建一个样式(style),不显示标题栏 不显示背景
                * 3、绑定布局,添加事件
                * 4、调用并显示
                * */
//自定义一个类,继承Dialog类
public class Mydialog extends Dialog {
    public Mydialog(@NonNull Context context) {
        super ( context, R.style.Mydialog );
        setContentView ( R.layout.my_dialog );
        Button confirm=findViewById ( R.id.confirm );
        Button cancel=findViewById ( R.id.cancel );
        confirm.setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                System.exit ( 0 );//退出程序
            }
        } );
        cancel.setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                dismiss ();
            }
        } );
    }
}
//调用并显示
 Mydialog mydialog=new Mydialog ( this );//自定义的类
 mydialog.setCancelable ( false );//默认为true(是否可退出对话框
mydialog.show ();
//创建一个样式(style),不显示标题栏 不显示背景
    <!--自定义一种样式-->
    <style name="Mydialog" parent="android:style/Theme.Dialog">
        <!-- Customize your theme here. -->
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>                                

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:background="#A29EA9"
    android:layout_height="wrap_content">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="提示"
        android:textSize="30dp"
        android:textStyle="bold"
        android:textColor="#fff"
        android:gravity="center"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#ffffff"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:text="你确定要执行吗?"
        android:textColor="#fff"
        android:gravity="center"
        android:textSize="20dp"/>
    <LinearLayout
        android:layout_marginHorizontal="80dp"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:gravity="center"
        android:orientation="horizontal">
        <Button
            android:id="@+id/confirm"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="10dp"
            android:text="确定"/>
        <Button
            android:id="@+id/cancel"
            android:layout_marginLeft="10dp"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="取消"/>
    </LinearLayout>
</LinearLayout>

10、比较特殊的对话框

如果你想做成这样:
效果图
可以利用:ArrayAdapter

                /*
                * 1、创建一个xml布局做资源
                * 2、添加ArrayAdapter
                * 3、setAdapter
                * */
     private void showdialog10() {
        final String[] strings={"Python","Java","C","C#","PHP","JavaScript","Object-C","Ruby"};
        ArrayAdapter adapter=new ArrayAdapter (this,R.layout.mydialog2,R.id.text1,strings  );//R.id.text1:指定控件
        AlertDialog.Builder dialog=new AlertDialog.Builder ( this );
        dialog.setTitle ( "请选择" );
        dialog.setAdapter ( adapter, new DialogInterface.OnClickListener () {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText ( activity_Dialog.this, strings[which], Toast.LENGTH_SHORT ).show ();
            }
        } );
        dialog.show ();
    }

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingVertical="10dp"
    android:gravity="center|left">
    <ImageView
        android:paddingLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher_round"/>
    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:textSize="30dp"
        android:textStyle="bold"
        android:text="Java"/>
</LinearLayout>

Activity生命周期详解

什么是生命周期
1、onCreate——创建(怀孕)
2、onStart——出生
3、onResume——可以交互(可点击可操作了)(可用了)
4、onPause——暂停了(可能生病了)
5、onStop——停止(老去)
6、onDestroy——被销毁了
7、onRestart——被销毁又活了(回光返照)
另外还有两个较重要的方法:
8、onBackPressed——当按返回时被触发
9、onSaveInstanceState——当程序被杀掉时执行触发
Activity生命周期

Activity之间的数据传递:

装在Intent对象中:
可以传:
——基本类型
——bundle对象
——序列化
put…
get…
如:

			//存数据
                Intent intent = new Intent ( life_activity.this, Main1_zhuye.class );
                Bundle bundle=new Bundle ();
                bundle.putString ( LIFE_DATA,"命名" );
                intent.putExtra ( "bundle",bundle );
                startActivity ( intent );
                //取数据
         if (getIntent ()!=null){
            Bundle bundle= getIntent ().getBundleExtra ( "bundle" );
            text.setText (bundle.getString ( life_activity.LIFE_DATA )  );
        }

当一个activity调用别一个activity,调用的activity销毁了,想返回数据到第一个activity:

	//调用的方式要换成startActivityForResult 
      Intent intent2=new Intent (life_activity2.this,Main1.class);
      Bundle bundle=new Bundle ();
      bundle.putString ( "key","第一个页面" );
      intent2.putExtra ( "key1", bundle);
       startActivityForResult (intent2 ,777 );
	//想返回数据可以在第二个页面加setResult
 	@Override
    protected void onDestroy() {
        super.onDestroy ();
        Intent intent=new Intent ();
        intent.putExtra ( "kkk","我是第二个页面关闭后返回的数据" );
        setResult (  111,intent);
        finish ();
    }
//第二个页面销毁后会回调第一个页面的onActivityResult方法,就可以接受返回的数据了
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult ( requestCode, resultCode, data );
        if (requestCode==777&&resultCode==111){
            String srt=data.getStringExtra ( "kkk" );
            text.setText ( srt );
        }
    }

Fragment:

在这里插入图片描述

一、Fragment与Activity的区别:
1、Fragment是到Android3.0以后出现的
2、一个Activity可以运行多个Fragment
3、Fragment不能脱离Activity而存在
4、Activity是屏幕的主体,而Fragment是Activity的一个组成员元素

Fragment的生命周期:
在这里插入图片描述
二、两种加载方法:
(一)、静态加载:xml

    <fragment
        android:id="@+id/fragment1"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:name="com.example.myapplication.Fragment.myfragment"/>

(二)、动态加载:

                getSupportFragmentManager ().
                	beginTransaction ().
                		replace ( R.id.line1, new myfragment_shez ()).
                			commit ();

切换:Add、Remove、Replace
三、传值:
(一)、Activity向Fragment传值:
在Fragment中加一个静态方法,并返回Fragment的实例,利用setArguments方法传值

    public static final String KEY = "key";

    public static myfragment_insert newfragemt_insert(String title) {
        myfragment_insert insertFragment=new myfragment_insert ();
        Bundle bundle=new Bundle ();
        bundle.putString ( KEY,title );
        insertFragment.setArguments ( bundle );
        return  insertFragment;
    }
    //取数据
            if (getArguments ()!=null){
            tilte = getArguments ().getString ( KEY );
        }

(二)、Activity向Fragment传值:利用接口回调

//1、fragment中写一个接口
//2、activity中实现接口,并调用setonTitleclickListener方法
    //接口写值方法
    public void setonTitleclickListener(onTitleclickListener onTitleclickListener){
        monTitleclickListener=onTitleclickListener;
    }
    private onTitleclickListener monTitleclickListener;//创建接口变量
    //定义接口
    public interface  onTitleclickListener{
        Void onclick(String title);
    }
    //2、activity中实现接口,并调用setonTitleclickListener方法(onTitleclickListener是我在myfragment_insert这个类中的定义的接口)
    public class Activity_fragment extends AppCompatActivity implements  myfragment_insert.onTitleclickListener {
    	@Override
	    public Void onclick(String title) {
	        setTitle ( title );
	        return null;
	    }
	    @Override
	    protected void onCreate(Bundle savedInstanceState) {
	                myfragment_insert activity_fragment = myfragment_insert.newfragemt_insert ( "Activity_fragment" );
	                getSupportFragmentManager ().beginTransaction ().replace ( R.id.line1, activity_fragment ).commit ();
	                activity_fragment.setonTitleclickListener ( this );//调用setonTitleclickListener
		}

}

二、Fragment的管理:
(一)、FragmentManager API
——FragmentManager用来管理Activity中的Fragmet
——findFragmentByid(通过id查找Activity中的Fragment
——findFragmentByTag(通过字符串查找Activity中的Fragment
——popBackStack(模拟用户的点击Back键的操作
——addOnBackStackChangedListener()添加后台栈改变监听器

(二)、FragmentTTransaction API
——add()向容器中添加一个Fragment
——remove()删除一个Fragment
——replace()将容器中的Fragment替换成新的Fragment
——hide()隐藏已存在的Fragment
——show()显示此前隐藏的Fragment
——addToBackStack()将事务添加到后台栈
——commit()提交事务,将改变应用到Activity

(三)、系统提供的Fragment:
系统提供了几个其他的Fragment类开发者可以继承:
1、DialogFragment —— 显示一个悬浮对话框
2、ListFragment —— 显示一个由adapter管理的项目列表

悬浮对话框:

//DialogFragment 的使用
    public static  class Mydialog extends DialogFragment {
        private String title;
        public static  Mydialog newDialogFragment(String title){
            Mydialog mydialog=new Mydialog ();
            Bundle bundle=new Bundle ();
            bundle.putString ( "title",title );
            mydialog.setArguments ( bundle );
            return mydialog;
        }

        @NonNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            title = getArguments ().getString ( "title" );
            Dialog dialog = new AlertDialog.Builder ( getActivity () )
            .setTitle ( title )
                    .setPositiveButton ( "确定", new DialogInterface.OnClickListener () {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText ( getActivity (), "ok", Toast.LENGTH_SHORT ).show ();
                        }
                    } )
                    .setNegativeButton ( "取消",null )
                    .create ();
            return dialog;
        }
    }

ListFragment :

   public static class mylistfragment extends ListFragment{
        private String[] data;
        public static mylistfragment newmylistfragment(String[] data){
            mylistfragment mylistfragment=new mylistfragment ();
            Bundle bundle=new Bundle ();
            bundle.putStringArray ( "data",data );
            mylistfragment.setArguments ( bundle );
            return mylistfragment;
        }

        @Override
        public void onAttach(@NonNull Context context) {
            super.onAttach ( context );
            data=getArguments ().getStringArray ( "data" );
            setListAdapter ( new ArrayAdapter<String> (
                    getActivity (),
                    android.R.layout.simple_expandable_list_item_1,
                    android.R.id.text1,
                    data
            ) );
        }
        @Override
        public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
            Toast.makeText ( getActivity (), data[position], Toast.LENGTH_SHORT ).show ();
            super.onListItemClick ( l, v, position, id );
        }
    }```

# 抽屉(DrawerLayout与ScrolView):
一、DrawerLayout

//DrawerLayout

<?xml version="1.0" encoding="utf-8"?>

<androidx.drawerlayout.widget.DrawerLayout 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=“match_parent”
tools:context=".DrawerLayout.drawerLayout"
android:orientation=“vertical”
android:id="@+id/drawer">


</androidx.drawerlayout.widget.DrawerLayout>

(二)、ScrolView
——ScrollView和HorzontalScrollView是为控件或者布局添加滚动条
——ScrollView和HorzontalScrollView只能有一个子控件
——SrollView用于设置垂直滚动条,HorizontalScrollView用于设置水平滚动条
注意:srrolView里面只能有一个控件或布局
# 消息处理机制
为什么要使用线程:
——当主线程执行的操作时间过长,就无法执行其他操作。消息队列中的消息无法处理,UI界面就不会更新,用户事件也不会处理。
——如果主线程执行一个操作超过5秒,Android可能会弹出一个应用程序没有响应的对话框,你的Activity可能会被杀掉。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200311132153794.png)
——常见的耗时操作如下:
			网络连接和网络疏忽的获取
			对存储器的读写
			大量的数据计算
一、消息队列(MessageQueue)
——Android采用一种复杂的Message Queue机制保证线程间通信
——Message Queue是一个信息队列,用来存放通过Handler发布的信息。Android在第一次启动程序时会默认为UI线程创建一个关联的消息队列,用来管理程序的组件,如Activity,Service,Broatcast Receiver等
——可以在工作线程中城建Handler与UI线程通信。

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200311135025696.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzk5OTE4Mg==,size_16,color_FFFFFF,t_70)![在这里插入图片描述](https://img-blog.csdnimg.cn/20200311133746277.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzk5OTE4Mg==,size_16,color_FFFFFF,t_70)
二、Handler的消息传递机制:
——工作线程可以通过Handler对象和主线程通讯
——Handler对象的所有工作将在主线程中执行
——Handler类需要实现handleMessage()方法,来处理信息队列中取出的Message对象。what值对应
——handlerMessage()方法由主线程调用,可以在需要的时候更新UI界面。但是必须确保次方法快速完成,因为其他UI操作会等待它完成才能执行。
——可以在Message中附加不同的参数
![](https://img-blog.csdnimg.cn/20200311135710721.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzk5OTE4Mg==,size_16,color_FFFFFF,t_70)
注意:子线程中是不可操作UI控件的
(一)、Handler处理

在这里插入代码片




三、xml解析:
//PullParser解析xml文件
public List<String> getXmlPullParser(Resources res,int id) throws XmlPullParserException, IOException {
    List<String> listdata = null;
    XmlPullParser xml=res.getXml ( id );
        int eventype=xml.getEventType ();
        while (eventype!=XmlPullParser.END_DOCUMENT){
            String gen=null;
            switch (eventype){
                case XmlPullParser.START_DOCUMENT://文档开始
                    // Log.i ( "tag","START_DOCUMENT" );
                    listdata=new ArrayList<> ();
                    break;
                case XmlPullParser.END_DOCUMENT://文档结束
                    //Log.i ( "tag","END_DOCUMENT" );
                    break;
                case XmlPullParser.START_TAG://标记(标签)开始
                    gen=xml.getName ();//取属性名
                    if (gen.equals ( "Button" )){
                        String value=xml.getAttributeValue ( 0 );//取属性的值
                        listdata.add ( value );
                        Log.i ( "tag","START_TAG:"+gen +"="+value);
                    }
                    break;
                case  XmlPullParser.END_TAG://标记(标签)结束
                    gen=xml.getName ();
                    Log.i ( "tag","END_TAG:"+gen );
                    break;
            }
            eventype=xml.next ();//下一个
        }
    return listdata;
}
四、josn解析:

一、JSON的概念:
——JSON(javascript object notation),是一种轻量级的数据存储贺交换格式
——它是完全独立于语言的文本格式
——JSON易于阅读、编写,也易于机器解析贺生成。

二、JSON基本格式:
——键值对对象格式:用“{}”包围
——数组格式:用“[]” 包围。
    /*
    * JSONObject:{}
    * JSONArray:数组([])
    * */
如:String data="{"name":"Tom"}";

/*
* json数据:

{
“data”: [
{
“id”: 12,
“url”: “”,
“br”: 0,
“size”: 0,
“md5”: null,
“code”: 404,
“expi”: 0,
“type”: null,
“gain”: 0,
“fee”: 0,
“uf”: null,
“payed”: 0,
“flag”: 0,
“canExtend”: false,
“freeTrialInfo”: null,
“level”: null,
“encodeType”: null
}
],
“code”: 200
}
* */
public void JOSN_string(String str) throws JSONException {
JSONObject object=new JSONObject (str);//取到json对象
JSONArray object1 = object.getJSONArray ( “data” );//取到json数组
for (int i=0;i<object1.length ();i++){
JSONObject data3 = object1.getJSONObject ( 0 );//取数组第一个
int id=data3.getInt ( “id” );//去属性值(键值对)
String url=data3.getString ( “url” );
int br=data3.getInt ( “br” );
int size=data3.getInt ( “size” );
String md5=data3.getString ( “md5” );
int code=data3.getInt ( “code” );
int expi=data3.getInt ( “expi” );
String type=data3.getString ( “type” );
int gain=data3.getInt ( “gain” );
int fee=data3.getInt ( “fee” );
String uf=data3.getString ( “uf” );
int payed=data3.getInt ( “payed” );
int flag=data3.getInt ( “flag” );
boolean canExtend=data3.getBoolean ( “canExtend” );
String freeTrialInfo=data3.getString ( “freeTrialInfo” );
String level=data3.getString ( “level” );
String encodeType=data3.getString ( “encodeType” );
Log.i ( “data”,id+","+url+","+br+","+size+","+md5+","+code+","+expi+","+type+
“,”+gain+","+fee+","+uf+","+payed+","+flag+","+canExtend+","+canExtend+","+freeTrialInfo
+","+level+","+encodeType
);
}
String object2 = object.getString ( “code” );
}

## Adapter适配器:
分类:ArrayAdapter、SimpleAdapter、BaseAdapter、ExpandableListAdapter

1、ArrayAdapter:

//简单适配器(ArrayAdapter)
private void adapter1() {
    final String[] data = {"AA", "BB", "CC", "AA", "BB", "CC", "AA", "BB", "CC"};
    ArrayAdapter<String> adapter = new ArrayAdapter<> (
            this,//上下文
            android.R.layout.simple_list_item_1,//布局
            android.R.id.text1,//数据显示控件id
            data//数据源
    );
    //事件
    listview.setOnItemClickListener ( new AdapterView.OnItemClickListener () {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            /*
             * parent:适配器
             * view:控件
             * position:索引
             * */
            Toast.makeText ( Activity_adapte.this, data[position], Toast.LENGTH_SHORT ).show ();
        }
    } );
    listview.setAdapter ( adapter );//绑定适配器
}
2、SimpleAdapter:

//适配器(SimpleAdapter)
private void adapter2() {
List<Map<String, Object>> listdata = new ArrayList ();
Map<String, Object> map = new HashMap<> ();
map.put ( “name”, “张三” );
map.put ( “age”, “18” );
listdata.add ( map );
Map<String, Object> map1 = new HashMap<> ();
map1.put ( “name”, “李四” );
map1.put ( “age”, “28” );
listdata.add ( map1 );
Map<String, Object> map3 = new HashMap<> ();
map3.put ( “name”, “蔡徐坤” );
map3.put ( “age”, “22” );
listdata.add ( map3 );
SimpleAdapter adapter1 = new SimpleAdapter (
this,//上下文
listdata,//数据源
R.layout.simple_1,//布局
new String[]{“name”, “age”},
new int[]{R.id.text1, R.id.text2}
);
listview.setAdapter ( adapter1 );
}


3、BaseAdapter :

//自定义的适配器
public class Myadapte extends BaseAdapter {
    int[] img={
            R.mipmap.list_my,
            R.mipmap.list_my_menu,
            R.mipmap.list_pwd,
            R.mipmap.list_safe_center,
            R.mipmap.list_save,
            R.mipmap.list_service
    };
    String[] name={
        "a","b","c","d","e","f"
    };
    //源数据的个数
    @Override
    public int getCount() {
        return img.length;
    }

    //索引项
    @Override
    public Object getItem(int position) {
        return position;
    }

    //索引项
    @Override
    public long getItemId(int position) {
        return position;
    }
    //项显示的view
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view;
        viewHolder holder;
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from ( Activity_adapte.this );//布局管理器
            view = inflater.inflate ( R.layout.simple_2, parent, false );//创建视图
            holder=new viewHolder ( view );//将视图交由viewHolder管理
        } else {
            view = convertView;
            holder= (viewHolder) convertView.getTag ();
        }
        ImageView imgage = holder.getview1 (  );
        TextView age = holder.getview2 (  );
        Button but1=holder.getview3 ();
        imgage.setImageResource ( img[position] );
        age.setText (name[position]  );
        but1.setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                Toast.makeText ( Activity_adapte.this, "点击了"+name[position], Toast.LENGTH_SHORT ).show ();
            }
        } );
        return view;
    }
    //管理控件的类,为了节约内存
    class viewHolder {
        private View view;
        private ImageView img;
        private TextView name;
        private Button but1;

        public viewHolder(View view) {
            this.view = view;
        }

        public ImageView getview1() {
            if (img == null) {
                img = view.findViewById ( R.id.img );
            }
            return img;
        }

        public TextView getview2() {
            if (name == null) {
                name = view.findViewById ( R.id.text );
            }
            return name;
        }
        public Button getview3() {
            if (but1 == null) {
                but1 = view.findViewById ( R.id.but1 );
            }
            return but1;
        }
    }
}
## 自定义控件:
——按类型划分,自定义View的实现方式可分为三种:
	自绘控件
	组合控件
	继承控件
一、自绘控件:
——在View上所展现的内容全部都是绘制出来的
——绘制的代码是写在onDraw()方法中的
——自定义的View在界面上显示,只需要像使用普通的控件一样来使用自定义View就可以了。

package com.example.myapplication.my_control;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.example.myapplication.R;
/*

  • 自绘控件

  • /
    public class MyView extends View implements Runnable{
    private Paint mpaint;//画笔
    private Bitmap mbitmap;
    private int x;
    private boolean flag;
    public MyView(Context context) {
    super ( context );
    inti();
    }
    /

    • 一代吗的方式动态加View到容器时使用
    • /
      public MyView(Context context, @Nullable AttributeSet attrs) {
      super ( context, attrs );
      inti();
      }
      /
    • 当以XML布局文件的方式使用时,自动调用
    • */
      public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
      super ( context, attrs, defStyleAttr );
      inti();
      }

    private void inti() {
    mpaint=new Paint ();
    mpaint.setColor ( Color.RED );//设置画笔颜色
    mpaint.setStyle ( Paint.Style.STROKE );//设置画笔样式
    mpaint.setStrokeWidth ( 3 );//设置画笔线条的宽度
    mbitmap= BitmapFactory.decodeResource ( getResources (), R.mipmap.find_hot_city );//取得位图
    mbitmap=mbitmap.createScaledBitmap ( mbitmap,1600,1400,true );//创建一个缩放的Bitmap对象
    }
    public void setFlag(boolean start){
    flag=start;
    }
    /*

    • canvas:画布

    • mpaint:画笔

    • */
      @Override
      protected void onDraw(Canvas canvas) {

      //canvas.drawCircle ( 50,50,50, mpaint);//绘制圆
      //canvas.drawRect ( 10,100,10,100,mpaint );//绘制矩形
      // canvas.drawBitmap ( mbitmap,10,10,null );//绘制图片
      moveBackground(canvas);
      super.onDraw ( canvas );
      }
      private void moveBackground(Canvas canvas){
      x-=5;
      int x2=mbitmap.getWidth ()-(-x);
      if (x2<=0){
      x=0;
      canvas.drawBitmap ( mbitmap,x,10,null );
      }else {
      canvas.drawBitmap ( mbitmap,x,10,null );
      canvas.drawBitmap ( mbitmap,x2,10,null );
      }
      }

    @Override
    public void run() {
    while (flag){
    //线程中不可以直接调用onDraw方法
    postInvalidate ();//在线程中要求View重新呈现
    }
    }
    }

二、自定义布局

1、用xml布局文件自定义布局

//自定义布局(用了一个xml布局文件)
public class My_layout extends LinearLayout {
private TextView text;
private Button but1;
private Context context;
public My_layout(Context context) {
super ( context );
this.context=context;
View view=inti();
}

public My_layout(Context context, @Nullable AttributeSet attrs) {
    super ( context, attrs );
    this.context=context;
    View view=inti();
    this.addView ( view );
}

public View inti() {
    LayoutInflater inflater=LayoutInflater.from ( context );
    View view=inflater.inflate ( R.layout.ling_layout,null );
    return view;
}

}

//xml文件

<?xml version="1.0" encoding="utf-8"?>





//使用
setContentView ( new My_layout );


2、纯java代码自定义布局

public class My_layout2 extends LinearLayout {
private TextView text;
private Button but1;
private Context context;
public My_layout2(Context context) {
super ( context );
this.context=context;
inti();
}

public My_layout2(Context context, @Nullable AttributeSet attrs) {
    super ( context, attrs );
    this.context=context;
    inti();
}
//要使用控件必须先new出来
public void inti() {
    text=new TextView ( context );
    but1=new Button ( context );
    LayoutParams params=new LayoutParams (280,LayoutParams.WRAP_CONTENT,1  );
    this.setOrientation ( LinearLayout.HORIZONTAL );//设置布局方向
    this.setBackgroundColor ( Color.RED );
    this.setLayoutParams ( params );
    this.addView ( but1 );
    this.addView ( text );
}

}
//使用
setContentView ( new My_layout2 );


三、	继承控件
——并不需要自己重头去实现一个控件,只需要去继承要给现有的控件,然后再这个控件上增加一些新的功能,就可以形成一个自定义的控件。
——继承控件的特点就是不仅能够按照我们的需求加入相应的功能,还可以保留原生控件的所有功能	。

public class MyView2 extends Button {
private int cx,cy;
private int radius;
private Paint mPaint;
private int paintColor;
public MyView2(Context context) {
super ( context );
init ();
}

public MyView2(Context context, AttributeSet attrs) {
    super ( context, attrs );
    init ();
}

public MyView2(Context context, AttributeSet attrs, int defStyleAttr) {
    super ( context, attrs, defStyleAttr );
    init ();
}

@Override
protected void onDraw(Canvas canvas) {
    int width=getWidth ();
    int height=getHeight ();
    cx=width/2;
    cy=height/2;
    radius=cx<cy?cy:cx;
    canvas.drawCircle ( cx,cy,radius,mPaint );
    super.onDraw ( canvas );
}
public void init(){
    mPaint=new Paint ();
    mPaint.setColor ( Color.RED );
    this.setText ( "" );
    this.setBackgroundColor ( Color.TRANSPARENT );
}
public void setPaintColor(int color){
    paintColor=color;
    mPaint.setColor ( paintColor );
    invalidate ();
}
//触屏监听器
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction ()){
        case MotionEvent.ACTION_DOWN:
            setPaintColor ( Color.YELLOW );
            return true;
        case MotionEvent.ACTION_UP:
            setPaintColor ( Color.RED );
            return true;
    }
    return super.onTouchEvent ( event );
}

}

### Listview、GridView、RecyclerView的使用:
一、ListView

二、GridView

三、RecyclerView


### Notification(通知栏信息)
——当系统想要不妨碍操作的情况下通知用户,可以使用Notification展示在屏幕最上方的通知栏内
——如果想要看详细的信息,拉下通知栏可以看到
——系统提供了对于Notification的服务,getSysoutService(NOTIFICATION_SERVICE)为我们返回一个通知服务的接口
——默认的通知栏布局
content title         Large icon
Content text 		Content info
Small icon 			Time

## Service的概念:
——Service是一种Android的组件 ,可以在后台长时间运行
——Service不提供界面交互
	即便用户跳转至另一个应用后,Service仍旧在后台运行
	任意应用组件都可以绑定服务,甚至可以用来完成进程间通讯的任务
			需要下载时
			播放音乐
			文件I/O、
一、Service的启动方式:
——Service可以通过两种方式来调用
		start
		一旦某个组件start一个Service后,Service开始独立运行,不在与原来的组件产生任何关系
		bind
		某个组件bind一个Service后,Service为组件提供一个接口,近似于客户端,会进行的交互
		
一、start

public class Service_list extends Service {
private String tag=“Service”;
/*
* 只有在生命周期第一次调用
* /
@Override
public void onCreate() {
Log.d ( tag,“onCreate” );
super.onCreate ();
}
/

* 每次startService启动都会调用
* */
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d ( tag,“onStartCommand” );
return super.onStartCommand ( intent, flags, startId );
}
@Override
public void onDestroy() {
Log.d ( tag,“onDestroy” );
super.onDestroy ();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}


注意:有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent  must be explitict,也就是说从Lollipop开始,service服务必须采用显示方式启动。
有两种解决方法:
1、设置Action和packageName:

Intent mIntent = new Intent();
mIntent.setAction(“XXX.XXX.XXX”);//你定义的service的action
mIntent.setPackage(getPackageName());//这里你需要设置你应用的包名
context.startService(mIntent);


2、将隐式启动转换为显示启动:

public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
//调用方式如下:
Intent mIntent = new Intent();
mIntent.setAction(“XXX.XXX.XXX”);
Intent eintent = new Intent(getExplicitIntent(mContext,mIntent));
context.startService(eintent);

二、bind

//Service
public class Service_list extends Service {
private String tag=“Service”;
/*
* 只有在生命周期第一次调用
* /
@Override
public void onCreate() {
Log.d ( tag,“onCreate” );
super.onCreate ();
}
/

* 每次startService启动都会调用
* /
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d ( tag,“onStartCommand” );
return super.onStartCommand ( intent, flags, startId );
}
@Override
public void onDestroy() {
Log.d ( tag,“onDestroy” );
super.onDestroy ();
}
/

* 只有在生命周期第一次调用
* */
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d ( tag,“onBind” );
return new Mybind ();
}
public class Mybind extends Binder {
public double avg(double…doubles){
int sum=0;
for (int i=0;i<doubles.length;i++){
sum+=doubles[i];
}
return sum/doubles.length;
}
}
}

//调用
public class Service2 extends AppCompatActivity implements View.OnClickListener {
private String tag = “Service”;
private Button but1;
private Button but2;
private Button but3;
private Button but4;
private Intent intent;
public Service_list.Mybind mybind;
ServiceConnection connection = new ServiceConnection () {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//连接成功,自动调用
mybind = (Service_list.Mybind) service;
Log.d ( tag, “onServiceConnected” );

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        //连接无效时调用

        Log.d ( tag, "onServiceDisconnected" );

    }
};
private EditText editText3;
private TextView text5;
private EditText editText2;
private TextView text4;
private EditText editText1;
private TextView text1;
private Button button;
private Button button4;
private TextView textView6;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate ( savedInstanceState );
    setContentView ( R.layout.activity_service2 );
    initView ();
}

private void initView() {
    editText3 = (EditText) findViewById ( R.id.editText3 );
    text5 = (TextView) findViewById ( R.id.text5 );
    editText2 = (EditText) findViewById ( R.id.editText2 );
    text4 = (TextView) findViewById ( R.id.text4 );
    editText1 = (EditText) findViewById ( R.id.editText1 );
    text1 = (TextView) findViewById ( R.id.text1 );
    button = (Button) findViewById ( R.id.button );

    button.setOnClickListener ( this );
    button4 = (Button) findViewById ( R.id.button4 );
    button4.setOnClickListener ( this );
    textView6 = (TextView) findViewById ( R.id.textView6 );
    textView6.setOnClickListener ( this );
}

@Override
public void onClick(View v) {
    switch (v.getId ()) {
        case R.id.button:
            intent = new Intent ();
            intent.setAction ( "com.example.myapplication.Service" );
            intent.setPackage ( getPackageName () );
            bindService ( intent, connection, BIND_AUTO_CREATE );
            break;
        case R.id.button4:
            double yu=Double.valueOf (editText1.getText ().toString ()  );
            double num=Double.valueOf (editText2.getText ().toString ()  );
            double yin=Double.valueOf (editText3.getText ().toString ()  );
            double a=mybind.avg ( yu,num,yin );
            textView6.setText ( "平均分数:"+a );
            break;
    }
}

}

三、系统服务:
1、由于是Android原生代码,可以通过Android代码来对服务进行交互
2、Android将Binder封装成普通的Manager类,代码调用时无法察觉是使用了Service
3、这些服务通过Context.getSystemService(String name)来获得
			name决定了获得不同的Manager类,不同的Manager类有各自的方法来调用系统功能或是访问系统状态
一、常用的系统服务:
1、POWER_SERVICE("power")	PowerManager电源管理
2、NOTIFICATION_SERVICE("notification")		NotificationManager通知的管理
3、LOCATION_SERVICE("location")		 LocationManager定位的控制
4、CONNECTIVITY_SERVICE("connection")		ConnectivityManager网络连接的管理

## ShraredPreference存储:
一、数据存储的意义:
——保存用户私有数据和配置
——比如音效设置,音乐文件,视频文件,短信,联系人
——需要在关机后重启仍能有效
——需要存储到外部介质中
二、使用SharedPrefreences
——一种轻量级的数据存取方法,以键值对来存储应用程序的配置信息
——只能存储基本的数据类型:boolean,float,int,long,string
——以XML文件的格式保存,位于/data/data/Package_name/shared_prefs目录下


## 文件存储:
——使用文件系统
——使用SDCard
一、使用文件系统:
——android使用的是基于Linux的文件系统,开发人员可以建立和访问程序自身的私有文件,也可以访问保存在资源目录中得原始文件和XML文件,还可以在SD卡等外部存储设备中保存文件。
——Android允许应用程序创建仅能够自身访问的私有文件,文件保存在设备的内部存储器上,在Linux系统上 的/data/data/<package_name>中。
		常用FileInputStream,FileOutputStream类结合openFileOutput,openFileInput方法完成对文件的读写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值