Android学习笔记-界面和数据存储以及一些零碎知识点

别再手动拷贝文件了!用Keil MDK的Pack Installer一键搞定STM32上的RT-Thread Nano移植 本文详细介绍了如何使用Keil MDK的Pack Installer一键快速移植RT-Thread Nano到STM32项目,告别繁琐的手动拷贝和配置过程。通过自动化版本管理和依赖处理,移植时间从47分钟缩短至3分钟,大幅提升开发效率。文章还提供了实战步骤、高级配置技巧和常见问题解决方案,帮助开发者轻松实现RTOS集成。 阅读详情

常见布局

相对布局

RelativeLayout
  • 组件默认左对齐、顶部对齐
  • 设置组件在指定组件的右边

     android:layout_toRightOf="@id/tv1"
    
  • 设置在指定组件的下边

    android:layout_below="@id/tv1"
    
  • 设置右对齐父元素

    android:layout_alignParentRight="true"
    
  • 设置与指定组件右对齐

     android:layout_alignRight="@id/tv1"
    

线性布局

LinearLayout
  • 指定各个节点的排列方向

    android:orientation="horizontal"
    
  • 设置右对齐

    android:layout_gravity="right"
    
  • 当竖直布局时,只能左右对齐和水平居中,顶部底部对齐竖直居中无效

  • 当水平布局时,只能顶部底部对齐和竖直居中
  • 使用match_parent时注意不要把其他组件顶出去
  • 线性布局非常重要的一个属性:权重

    android:layout_weight="1"
    
  • 权重设置的是按比例分配剩余的空间

帧布局

FrameLayout
  • 默认组件都是左对齐和顶部对齐,每个组件相当于一个div
  • 可以更改对齐方式

    android:layout_gravity="bottom"
    
  • 不能相对于其他组件布局

表格布局

TableLayout
  • 每个节点是一行,它的每个子节点是一列
  • 表格布局中的节点可以不设置宽高,因为设置了也无效

    • 根节点的子节点宽为匹配父元素,高为包裹内容
    • 节点的子节点宽为包裹内容,高为包裹内容
    • 以上默认属性无法修改
  • 根节点中可以设置以下属性,表示让第1列拉伸填满屏幕宽度的剩余空间

    android:stretchColumns="1"
    

绝对布局

AbsoluteLayout
  • 直接指定组件的x、y坐标

    android:layout_x="144dp"
    android:layout_y="154dp"
    

logcat

  • 日志信息总共分为5个等级
    • verbose
    • debug
    • info
    • warn
    • error
  • 定义过滤器方便查看
  • System.out.print输出的日志级别是info,tag是System.out
  • Android提供的日志输出api

    Log.v(TAG, "加油吧,童鞋们");
    Log.d(TAG, "加油吧,童鞋们");
    Log.i(TAG, "加油吧,童鞋们");
    Log.w(TAG, "加油吧,童鞋们");
    Log.e(TAG, "加油吧,童鞋们");
    

文件读写操作

  • Ram内存:运行内存,相当于电脑的内存
  • Rom内存:内部存储空间,相当于电脑的硬盘
  • sd卡:外部存储空间,相当于电脑的移动硬盘

在内部存储空间中读写文件

小例子:用户输入账号密码,勾选“记住账号密码”,点击登录按钮,登录的同时持久化保存账号和密码

1. 定义布局
2. 完成按钮的点击事件
  • 弹Toast提示用户登录成功
        Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
3. 拿到用户输入的数据
  • 判断用户是否勾选保存账号密码
        CheckBox cb = (CheckBox) findViewById(R.id.cb);
        if(cb.isChecked()){
            ......
        }
4. 开启io流把文件写入内部存储
  • 直接开启文件输出流写数据
        //持久化保存数据
            File file = new File("data/data/com.dimon.example/info.txt");
            FileOutputStream fos = new FileOutputStream(file);
            fos.write((name + "##" + pass).getBytes());
            fos.close();
  • 读取数据前先检测文件是否存在
        if(file.exists())
  • 读取保存的数据,也是直接开文件输入流读取
        File file = new File("data/data/com.dimon.example/info.txt");
        FileInputStream fis = new FileInputStream(file);
        //把字节流转换成字符流
        BufferedReader br = new BufferedReader(new InputStreamReader(fis));
        String text = br.readLine();
        String[] s = text.split("##");
  • 读取到数据之后,回显至输入框
        et_name.setText(s[0]);
        et_pass.setText(s[1]);

使用路径api读写文件

  • getFilesDir()得到的file对象的路径是data/data/com.dimon.example/files
    • 存放在这个路径下的文件,只要你不删,它就一直在
  • getCacheDir()得到的file对象的路径是data/data/com.dimon.example/cache

    • 存放在这个路径下的文件,当内存不足时,有可能被删除
  • 系统管理应用界面的清除缓存,会清除cache文件夹下的东西,清除数据,会清除整个包名目录下的东西


在外部存储读写数据

sd卡的路径

  • sdcard:2.3之前的sd卡路径
  • mnt/sdcard:4.3之前的sd卡路径
  • storage/sdcard:4.3之后的sd卡路径

  • 最简单的打开sd卡的方式

        File file = new File("sdcard/info.txt");
  • 写sd卡需要权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
  • 读sd卡,在4.0之前不需要权限,4.0之后可以设置为需要

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
  • 使用api获得sd卡的真实路径,部分手机品牌会更改sd卡的路径

    Environment.getExternalStorageDirectory()
    
  • 判断sd卡是否准备就绪

        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))

获取sd卡剩余容量的代码

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    File path = Environment.getExternalStorageDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize;
        long totalBlocks;
        long availableBlocks;

        //获取当前系统版本的等级
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
           blockSize = stat.getBlockSizeLong();
             totalBlocks = stat.getBlockCountLong();
             availableBlocks = stat.getAvailableBlocksLong();
        }
        else{
          blockSize = stat.getBlockSize();
            totalBlocks = stat.getBlockCount();
            availableBlocks = stat.getAvailableBlocks();
        }

        TextView tv = (TextView) findViewById(R.id.tv);
        tv.setText(formatSize(availableBlocks * blockSize));//剩余容量
  }

  private String formatSize(long size) {
        return Formatter.formatFileSize(this, size);
    }

Linux文件的访问权限

  • 在Android中,每一个应用是一个独立的用户
  • 使用10个字母表示
  • drwxrwxrwx
  • 第1位:d表示文件夹,-表示文件
  • 第2-4位:rwx,表示这个文件的拥有者用户(owner)对该文件的权限
    • r:读
    • w:写
    • x:执行
  • 第5-7位:rwx,表示跟文件拥有者用户同组的用户(grouper)对该文件的权限
  • 第8-10位:rwx,表示其他用户组的用户(other)对该文件的权限

openFileOutput的四种模式

  • MODE_PRIVATE:-rw-rw—-
  • MODE_APPEND:-rw-rw—-
  • MODE_WORLD_WRITEABLE:-rw-rw–w-
  • MODE_WORLD_READABLE:-rw-rw-r–

SharedPreference

用SharedPreference存储账号密码

  • 往SharedPreference里写数据
        //拿到一个SharedPreference对象
        SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
        //拿到编辑器
        Editor ed = sp.edit();
        //写数据
        ed.putBoolean("name", name);
        ed.commit();
  • 从SharedPreference里取数据
        SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
        //从SharedPreference里取数据
        String name = sp.getBoolean("name", "");

生成XML文件备份短信

  • 创建几个虚拟的短信对象,存在list中
  • 备份数据通常都是备份至sd卡

使用StringBuffer拼接字符串

  • 把整个xml文件所有节点append到sb对象里
        sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
        //添加smss的开始节点
        sb.append("<smss>");
        .......
  • 把sb写到输出流中
        fos.write(sb.toString().getBytes());

使用XMl序列化器生成xml文件

  • 得到xml序列化器对象
        XmlSerializer xs = Xml.newSerializer();
  • 给序列化器设置输出流
        File file = new File(Environment.getExternalStorageDirectory(), "backupsms.xml");
        FileOutputStream fos = new FileOutputStream(file);
        //给序列化器指定好输出流
        xs.setOutput(fos, "utf-8");//enconding:指定用什么编码生成xml文件
  • 开始生成xml文件
        //enconding:指定头结点中的enconding属性的值
        xs.startDocument("utf-8", true);
        xs.startTag(null, "smss");
        ......
        xs.endTag(null, "smss");
        //告诉序列化器,文件生成完毕
        xs.endDocument();

pull解析xml文件

  • 先自己写一个xml文件,存一些天气信息

拿到xml文件

        InputStream is = getClassLoader().getResourceAsStream("weather.xml");

拿到pull解析器

        XmlPullParser xp = Xml.newPullParser();

开始解析

  • 拿到指针所在当前节点的事件类型
        int type = xp.getEventType();
  • 事件类型主要有五种

    • START_DOCUMENT:xml头的事件类型
    • END_DOCUMENT:xml尾的事件类型
    • START_TAG:开始节点的事件类型
    • END_TAG:结束节点的事件类型
    • TEXT:文本节点的事件类型
  • 如果获取到的事件类型不是END_DOCUMENT,就说明解析还没有完成,如果是,解析完成,while循环结束

        while(type != XmlPullParser.END_DOCUMENT)
  • 当我们解析到不同节点时,需要进行不同的操作,所以判断一下当前节点的name
    • 当解析到weather的开始节点时,new出list
    • 当解析到city的开始节点时,创建city对象,创建对象是为了更方便的保存即将解析到的文本
    • 当解析到name开始节点时,获取下一个节点的文本内容,temp、pm也是一样
            case XmlPullParser.START_TAG:
            //获取当前节点的名字
                if("weather".equals(xp.getName())){
                    citys = new ArrayList<City>();
                }
                else if("city".equals(xp.getName())){
                    city = new City();
                }
                else if("name".equals(xp.getName())){
                    //获取当前节点的下一个节点的文本
                    String name = xp.nextText();
                    city.setName(name);
                }
                else if("temp".equals(xp.getName())){
                    String temp = xp.nextText();
                    city.setTemp(temp);
                }
                else if("pm".equals(xp.getName())){
                    String pm = xp.nextText();
                    city.setPm(pm);
                }
                break;
  • 当解析到city的结束节点时,说明city的三个子节点已经全部解析完了,把city对象添加至list
        case XmlPullParser.END_TAG:
            if("city".equals(xp.getName())){
                    citys.add(city);
            }

换行符也是文本节点


SQLite数据库

  • 轻量级关系型数据库
  • 创建数据库需要使用的api:SQLiteOpenHelper
            //arg1:数据库文件的名字
            //arg2:游标工厂
            //arg3:数据库版本
            public MyOpenHelper(Context context, String name, CursorFactory factory, int version){}

必须定义一个构造方法:
数据库被创建时会调用:onCreate方法
数据库升级时会调用:onUpgrade方法

创建数据库

    //创建OpenHelper对象
    MyOpenHelper oh = new MyOpenHelper(getContext(), "person.db", null, 1);
    //获得数据库对象,如果数据库不存在,先创建数据库,后获得,如果存在,则直接获得
    SQLiteDatabase db = oh.getWritableDatabase();
  • getWritableDatabase():打开可读写的数据库
  • getReadableDatabase():在磁盘空间不足时打开只读数据库,否则打开可读写数据库
  • 在创建数据库时创建表
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            db.execSQL("create table person (_id integer primary key autoincrement, name char(10), phone char(20), money integer(20))");
        }

数据库的增删改查

SQL语句

  • insert into person (name, phone, money) values (‘张三’, ‘159874611’, 2000);
  • delete from person where name = ‘李四’ and _id = 4;
  • update person set money = 6000 where name = ‘李四’;
  • select name, phone from person where name = ‘张三’;

执行SQL语句实现增删改查

        //插入
        db.execSQL("insert into person (name, phone, money) values (?, ?, ?);", new Object[]{"张三", 15987461, 75000});
        //查找
        Cursor cs = db.rawQuery("select _id, name, money from person where name = ?;", new String[]{"张三"});
  • 测试方法执行前会调用此方法
        protected void setUp() throws Exception {
            super.setUp();
            //                  获取虚拟上下文对象
            oh = new MyOpenHelper(getContext(), "people.db", null, 1);
        }

使用api实现增删改查

  • 插入
        //以键值对的形式保存要存入数据库的数据
        ContentValues cv = new ContentValues();
        cv.put("name", "王陆");
        cv.put("phone", 1651646);
        cv.put("money", 3500);
        //返回值是改行的主键,如果出错返回-1
        long i = db.insert("person", null, cv);
  • 删除
        //返回值是删除的行数
        int i = db.delete("person", "_id = ? and name = ?", new String[]{"1", "张三"});
  • 修改
        ContentValues cv = new ContentValues();
        cv.put("money", 25000);
        int i = db.update("person", cv, "name = ?", new String[]{"赵四"});
  • 查询
        //arg1:要查询的字段
        //arg2:查询条件
        //arg3:填充查询条件的占位符
        Cursor cs = db.query("person", new String[]{"name", "money"}, "name = ?", new String[]{"张三"}, null, null, null);
        while(cs.moveToNext()){
            //                          获取指定列的索引值
            String name = cs.getString(cs.getColumnIndex("name"));
            String money = cs.getString(cs.getColumnIndex("money"));
            System.out.println(name + ";" + money);
        }

事务

  • 保证多条SQL语句要么同时成功,要么同时失败
  • 最常见案例:银行转账
  • 事务api
        try {
            //开启事务
            db.beginTransaction();
            ...........
            //设置事务执行成功
            db.setTransactionSuccessful();
        } finally{
            //关闭事务
            //如果此时已经设置事务执行成功,则sql语句生效,否则不生效
            db.endTransaction();
        }

把数据库的数据显示至屏幕

  1. 任意插入一些数据
    • 定义业务bean:Person.java
    • 读取数据库的所有数据
        Cursor cs = db.query("person", null, null, null, null, null, null);
        while(cs.moveToNext()){
            String name = cs.getString(cs.getColumnIndex("name"));
            String phone = cs.getString(cs.getColumnIndex("phone"));
            String money = cs.getString(cs.getColumnIndex("money"));
            //把读到的数据封装至Person对象
            Person p = new Person(name, phone, money);
            //把person对象保存至集合中
            people.add(p);
        }
  • 把集合中的数据显示至屏幕
         LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
         for(Person p : people){
             //创建TextView,每条数据用一个文本框显示
             TextView tv = new TextView(this);
             tv.setText(p.toString());
             //把文本框设置为ll的子节点
             ll.addView(tv);
         }

添加ScrollView使得滑动

<ScrollView>
......
</ScrollView>
  • 分页查询
        Cursor cs = db.query("person", null, null, null, null, null, null, "0, 10");

ListView

  • 就是用来显示一行一行的条目的
  • MVC结构
    • M:model模型层,要显示的数据 javaBean ————people集合
    • V:view视图层,用户看到的界面 jsp ————ListView
    • c:control控制层,操作数据如何显示 servlet ————adapter对象
  • 每一个条目(Item)都是一个View对象

BaseAdapter

  • 必须实现的两个方法

第一个

            //系统调用此方法,用来获知模型层有多少条数据
            @Override
            public int getCount() {
                return people.size();
            }

第二个:position:是return的View对象所对应的数据在集合中的位置

            //系统调用此方法,获取要显示至ListView的View对象
            //position:是return的View对象所对应的数据在集合中的位置
      //position:本次getView方法调用所返回的view对象,在listView中是处于第几个条目,那么position的值就是多少
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                System.out.println("getView方法调用" + position);
                TextView tv = new TextView(MainActivity.this);
                //拿到集合中的元素
                Person p = people.get(position);
                tv.setText(p.toString());

                //把TextView的对象返回出去,它会变成ListView的条目
                return tv;
            }
  • 屏幕上能显示多少个条目,getView方法就会被调用多少次,屏幕向下滑动时,getView会继续被调用,创建更多的View对象显示至屏幕

条目的缓存

  • 当条目划出屏幕时,系统会把该条目缓存至内存,当该条目再次进入屏幕,系统在重新调用getView时会把缓存的条目作为convertView参数传入,但是传入的条目不一定是之前被缓存的该条目,即系统有可能在调用getView方法获取第一个条目时,传入任意一个条目的缓存

提升ListView的运行效率

public class NewsAdapter extends ArrayAdapter<News> {

    private int resourceId;

    public NewsAdapter(Context context, int textViewResourceId, List<News> objects) {
        super(context, textViewResourceId, objects);
        resourceId = textViewResourceId;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        News news = getItem(position);
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);
            viewHolder = new ViewHolder();
            viewHolder.newsTitleText = (TextView) view.findViewById(R.id.news_title);
            view.setTag(viewHolder);//将ViewHolder存储在View中
        } else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();//重新获取ViewHolder
        }
        //TextView newsTitleText = (TextView) view.findViewById(R.id.news_title);

        viewHolder.newsTitleText.setText(news.getTitle());
        return view;
    }

    class ViewHolder {
      TextView newsTitleText;
    }
}

对话框

确定取消对话框

  • 创建对话框构建器对象,类似工厂模式
        AlertDialog.Builder builder = new Builder(this);
  • 设置标题和正文
        builder.setTitle("警告");
        builder.setMessage("愤怒香蕉更新啦!!");
  • 设置确定和取消按钮
        builder.setPositiveButton("马上去水一贴", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this, "恭喜你水贴成功,现在程序退出", 0).show();
            }
        });

        builder.setNegativeButton("下次再说", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                Toast.makeText(MainActivity.this, "蕉姐这肥羊可以宰了呀", 0).show();
            }
        });
  • 使用构建器创建出对话框对象
        AlertDialog ad = builder.create();
        ad.show();

单选对话框

        AlertDialog.Builder builder = new Builder(this);
        builder.setTitle("选择你的性别");
  • 定义单选选项
        final String[] items = new String[]{
                "男", "女", "其他"
        };
        //-1表示没有默认选择
        //点击侦听的导包要注意别导错
        builder.setSingleChoiceItems(items, -1, new OnClickListener() {

            //which表示点击的是哪一个选项
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "您选择了" + items[which], 0).show();
                //对话框消失
                dialog.dismiss();
            }
        });

        builder.show();

多选对话框

        AlertDialog.Builder builder = new Builder(this);
        builder.setTitle("请选择你欲修炼之功法");
  • 定义多选的选项,因为可以多选,所以需要一个boolean数组来记录哪些选项被选了
        final String[] items = new String[]{
                "无相神功",
                "仰望星空",
                "千年杀",
                "龙阳神功"
        };
        //true表示对应位置的选项被选了
        final boolean[] checkedItems = new boolean[]{
                true,
                false,
                false,
                false,
        };
        builder.setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() {

            //点击某个选项,如果该选项之前没被选择,那么此时isChecked的值为true
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                checkedItems[which] = isChecked;
            }
        });

        builder.setPositiveButton("确定", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                StringBuffer sb = new StringBuffer();
                for(int i = 0;i < items.length; i++){
                    sb.append(checkedItems[i] ? items[i] + " " : "");
                }
                Toast.makeText(MainActivity.this, sb.toString(), 0).show();
            }
        });
        builder.show();

将这些零碎的知识点笔记整理出来,方便以后查找翻看。(^__^) 谢谢阅读~

AI一键生成带货短视频:电商直播的未来 随着电子商务行业的快速发展,直播带货已成为一种极为有效的营销手段。然而,传统的人工直播方式存在诸多局限性,如人力成本高、主播培训周期长等问题。为了解决这些挑战,一种基于AI技术的一键生成带货视频解决方案应运而生——这就是“Anchor Crafter”。这项创新技术不仅能够自动创建高质量的带货视频,而且还能实现人物与商品之间的自然交互,极大地提升了用户体验。 阅读详情

相关推荐

用Java和MQTT搞定大疆无人机自动巡检:一个真实机场项目的踩坑与优化记录

本文详细介绍了如何利用Java和MQTT协议实现大疆无人机在机场自动巡检系统的开发与优化。通过实战案例分享系统架构设计、通信协议选型、断线重连机制及数据通道优化等关键环节,帮助开发者解决GPS信号漂移、MQTT消息风暴等典型问题,提升系统性能和可靠性。

weixin_30275415的博客 495

Android学习笔记

Android 文章目录Android零、零碎0.1 横竖屏0.2 标题一、View视图1.1 相对布局-RelativeLayout1.2 线性布局-LinearLayout1.3 表格布局-TableLayout二、界面控件2.1 Button 事件1。新建方法2。new一个监听3。实例2.2 EditText2.3 ImageView +Radio + CheckBox2.4 Toast2.5 **AlertDialog**1. 简单Dialog2. 带有单选的Dialog2.6 ListVie**w

weixin_45653525的博客 815

4D Gaussian Splatting for Real-Time Dynamic Scene Rendering-4DGS阅读笔记

为了实现实时动态场景渲染,同时还能具备较高的训练和存储效率,作者提出了四维高斯溅射(4D-GS)方法,将其作为动态场景的一种整体表示方式,而不是对每个单独的帧应用三维高斯溅射(3D-GS)方法。在 4D-GS 中,提出了一种新颖的显式表示方法,它同时包含三维高斯模型和四维神经体素。受 HexPlane 启发,提出了一种分解的神经体素编码算法,以高效地从四维神经体素构建高斯特征,然后应用一个轻量级多层感知器(MLP)来预测在新时间戳下的高斯变形。

2403_85515624的博客 2343

学习android零碎知识点笔记 preference【转载】

原帖子地址:http://liangruijun.blog.51cto.com/3061169/658521 一.Preference的简介     Preference(配置)提供了一种轻量级的数据存取方法,主要应用于数据比较少的配置信息。它以“key-value”(是一个Map)对的方式将数据保存在一个XML配置文件中,例如,手机的开机问候语,可以将其以Preference

qq_34987771的博客 357

Tlsr8258开发-程序烧写

开源一小步,进步一大步

自学嵌入式 1774

国产大模型高考横评:数学推理与教育落地能力实测

大模型能力评估正从开放榜单转向封闭任务的确定性验证,高考作为强逻辑、低容错、高精度的标准化考试,成为检验模型真实推理能力的理想标尺。其核心在于考察知识覆盖、步骤完整性、单位敏感性与教学对齐度,而非单纯答案正确率。数学解答题尤其凸显模型在前提校验、条件枚举与过程可控性上的差异,反映出训练数据与教育语料深度耦合带来的工程化优势。该范式已延伸至语文语感建模、英语表达习惯适配及理综跨学科缝合等场景,为智能阅卷、精准答疑和教培系统集成提供可复现、可解释、可部署的技术依据。

weixin_30436581的博客 287

Android零碎知识

1 Android存取图片最好使用PNG格式的。 2

weixin_34332905的博客 63

Openclaw 错误分析 与 解决方案 之:Selected model is at capacity. Try a different model, or wait and retry.

Openclaw 错误分析 与 解决方案 :Selected model is at capacity. Try a different model, or wait and retry.

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 6415

2018年android面试分享和学习总结

概述 成果和收获 面试分享 Android JVM Java 线程 Java 集合 网络 数据结构和算法 写在最后 概述 回顾历史不忘初心 展望未来继续前行。 17年零零碎碎也捣鼓了好一阵子,从Android 自定义View开始,到源码分析,设计模式,再到JVM的了解以及最近看完的Java线程和并发以及集合。对Android体系有了一个大概了认识和了解。 成果和...

凶残的程序员 7823

[网络安全自学篇] 二.Chrome浏览器保留密码功能渗透解析及登录加密入门笔记

最近开始学习网络安全相关知识,接触了好多新术语,感觉自己要学习的东西太多,真是学无止境,也发现了好几个默默无闻写着博客、做着开源的大神。接下来系统分享一些网络安全的自学笔记,希望读者们喜欢。 上一篇文章分享了看雪Web安全总结知识和一个异或解密的示例,本篇文章着重讲解Chrome浏览器保留密码功能渗透解析及登录加密入门笔记,结合实际例子一步步实现浏览器漏洞的挖掘。非常基础的文章,希望对入门的博友们有帮助,大神请飘过,谢谢各位看官!

杨秀璋的专栏 2万+

部署OpenClaw时设置环境变量提示export: not valid in this context的完整解决方案

OpenClaw环境变量设置错误解决方案 问题概述 在部署OpenClaw时设置环境变量出现"export: not valid in this context"错误,通常由以下原因导致: 在非交互式shell中使用export命令 在命令替换或管道中使用export 脚本文件包含Windows换行符(CRLF) 解决方案 修正脚本执行方式:确保export命令在正确的shell上下文中使用 使用source命令:通过. setup_openclaw.sh或source setup_op

博客 457

别瞎学了,面试官会问的点都给你整理好了,《Android面试“一百问”》

概述 回顾历史不忘初心 展望未来继续前行。 20年零零碎碎也捣鼓了好一阵子,从Android 自定义View开始,到源码分析,设计模式,再到JVM的了解以及最近看完的Java线程和并发以及集合。对Android体系有了一个大概了认识和了解。 成果和收获 可以说博客和github对于面试有一定的加分项,原本一开始写博客的目的是因为公众号,博客平台等一些大V的建议,不过到后来发现写技术博客的过程中,不仅能够对知识的深入认识和掌握,还能够提升对该知识的记忆和印象。因为虽然写博客会比较耗时,不过对知识的梳理

Androidbye的博客 1615

Dify搭建AI测试用例生成器

1、获取产品需求文档2、解读、分析、挖掘需求点,提炼为测试点3、依据测试点,生成详细的测试用例4、输出测试用例1、打开 Dify 控制台,依次点击【工作室】-【ChatFlow】-【创建空白应用】。

十二测试录 1370

我的Android博文整理汇总

时间久了,零碎的知识点容易忘,现在从头梳理Android中各个模块的知识结构,总结成文。Intent相关博文: Android中Intent概述及使用 Android中Intent对象与Intent Filter过滤匹配过程详解 Android中常见Intent习惯用法-上篇(附源码下载)Handler相关博文: Android中Handler的使用 深入源码解析Android中的

孙群 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

2020年Android面试分享和学习总结:历经一年如愿进入大厂

作者:月清影 概述 回顾历史不忘初心 展望未来继续前行。 19年零零碎碎也捣鼓了好一阵子,从Android 自定义View开始,到源码分析,设计模式,再到JVM的了解以及最近看完的Java线程和并发以及集合。对Android体系有了一个大概了认识和了解。 成果和收获 可以说博客和github对于面试有一定的加分项,原本一开始写博客的目的是因为公众号,博客平台等一些大V的建议,不过到后来发现写技术博客的过程中,不仅能够对知识的深入认识和掌握,还能够提升对该知识的记忆和印象。因为虽然写博客会比较耗时,不过对.

1 251

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android基础教程——从入门到精通(上)_生皮鞣制工艺流程

/这里表示设置意图动作为准备拨号如果想要跳转到自己定义的activity:步骤一:在AndroidManifest.xml找到该activity,添加action和category标签,同时设置exported为true,表示允许被其他activity调用。

2401_87254499的博客 1796

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android Contacts源码解析

Android contacts 联系人 通讯录 源码 完全解析 1简介 2软件架构 3各功能模块分析 1联系人数据的显示 1联系人列表显示 2联系人详细信息数据的显示 2联系人数据的编辑和存储 1编辑界面相关 2数据存储相关 3Sim联系人数据的整合 1Sim卡联系人数据的显示 2开机自动导入Sim卡联系人 3telephony中IccProvider浅析 4Sim卡联系人的手动导入...

skysukai的博客 6249

Android contacts 联系人 通讯录 源码 完全解析

Android contacts 联系人 通讯录 源码 完全解析 1简介2软件架构3各功能模块分析 1联系人数据的显示 1联系人列表显示2联系人详细信息数据的显示 2联系人数据的编辑和存储 1编辑界面相关2数据存储相关 3Sim联系人数据的整合 1Sim卡联系人数据的显示2开机自动导入Sim卡联系人3telephony中IccProvider浅析4Sim卡联系

dxmcu的专栏 1万+

2021年Android进阶者的新篇章,成功拿下大厂offer

前言 说起程序员人们的第一印象就是工资高、加班凶、话少钱多头发少。再加上现在科技互联网公司太吃香,bat、华为小米等公司程序员加班情况被广泛传播,程序员用生命在敲代码的印象刻在了很多人的心里。 与其它行业一样,凡是有高级和普通,虽然都是敲代码但也有大牛和普通之分,大牛程序员,一个人比一个团队做项目都做得快,最为出名的当属十几年前求伯君在做wps时,一个人完成了微软二十人团队没有完成的项目需求,也让wps在与微软的竞争中站稳了脚跟。程序员的能力差距真的比贫富的差距还要大。 项目实战 启动速度 流畅度 抖音

m0_56228922的博客 137

Android软件开发之数据的操作详解

Android软件开发之数据的新建 储存 读取 删除 1.使用SharedPreferences处理数据的 新建 储存 读取 删除 SharedPreferences保存后生成的是XML文件,内容是以节点的形势保存在文件中,SharedPreferences类提供了非常丰富的处理数据的方法下面我向大家介绍一下如何使用SharedPreferences来处理数据。 输入须要保存的内容

何晓龙的博客 332

BAT等大厂所封杀的Android面试秘籍汇总(1)

Objectequals 方法hashCode 方法staticfinalString、StringBuffer、StringBuilder异常处理内部类匿名内部类多态抽象和接口集合框架HashMap结构图HashMap 的工作原理HashMap 与 HashTable 对比ConcurrentHashMapBase 1.7Base 1.8ArrayListLinkedListCopyOnWriteArrayList反射单例饿汉式双重检查模式静态内部类模式线程状态状态控制volatilesynchroniz

2401_84412961的博客 725

Android博文整理汇总

Android博文整理汇总

Think Different 760

Android 软件开发之数据的 新建 储存 读取 删除 详解(十四)

Android软件开发之数据的新建 储存 读取 删除雨松MOMO原创文章如转载,请注明:转载至我的独立域名博客雨松MOMO程序研究院,原文地址:http://www.xuanyusong.com/archives/118 1.使用SharedPreferences处理数据的 新建 储存 读取 删除        SharedPreferences保存后生成的是XML文件,内容是以节点的形势保存在文

雨松MOMO的程序世界专栏 1万+

【Android项目实战 | 从零开始写app一一智慧服务】完结篇&系列导航篇、源代码

目录 介绍: 涉及知识: 系列汇总 项目源代码 文章介绍 本系列小文是一个简单的Android app项目实战,对于刚入门Android 的初学者来说,基础学完了,但是怎么综合的去写一个小app,可能无从下手,包括我自己当初入门也是一样的,不知道怎么写。。。通过空闲更上这个案例,让零碎的基础综合起来,知道怎么去用!当然去B站看实战小案例也是可以学习到的。在这些案例之中,能实现的方法可能有很多,例如实现网络请求的框架很多,像volley、android-async-http、HttpURLCon.

go 3万+

android 文件操作

1.使用SharedPreferences处理数据的 新建 储存 读取 删除      SharedPreferences保存后生成的是XML文件,内容是以节点的形势保存在文件中,SharedPreferences类提供了非常丰富的处理数据的方法下面我向大家介绍一下如何使用SharedPreferences来处理数据。   保存成功以后,数据被保存到了data路径下 /当前包名 (红框内

aiqing0119的专栏 784
上一篇: Android学习笔记-网络编程
下一篇: 关于单元测试
朴哲
博客等级 码龄11年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值