Android SQLite (二) 基本用法

在Android开发中SQLite起着很重要的作用,网上SQLite的教程有很多很多,不过那些教程大多数都讲得不是很全面。本人总结了一些SQLite的常用的方法,借着论坛的大赛,跟大家分享分享的。

一.SQLite的介绍

1.SQLite简介

SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入  式的,而且目前已经在很多嵌入式产品中使用了它,它占用 资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持 Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如Tcl、PHP、Java、C++、.Net等,还有 ODBC接口,同样比起 Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。

2.SQLite的特点:

  • 轻量级

SQLite 和C/S模式的数据库软件不同,它是进程内的数据库引擎,因此不存在数据库的客户端和服务器。使用SQLite一般只需要带上它的一个动态  库,就可以 享受它的全部功能。而且那个动态库的尺寸也挺小,以版本3.6.11为例,Windows下487KB、Linux下347KB。

  • 不需要”安装”

SQLite的核心引擎本身不依赖第三方的软件,使用它也不需要”安装”。有点类似那种绿色软件。

  • 单一文件

数据库中所有的信息(比如表、视图等)都包含在一个文件内。这个文件可以自由复制到其它目录或其它机器上。

  • 跨平台/可移植性

除了主流操作系统 windows,linux之后,SQLite还支持其它一些不常用的操作系统。

  • 弱类型的字段

同一列中的数据可以是不同类型

  • 开源

这个相信大家都懂的!!!!!!!!!!!!

3.SQLite数据类型

一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断。SQLite具有以下五种常用的数据类型:

NULL: 这个值为空值

VARCHAR(n):长度不固定且其*大长度为 n 的字串,n不能超过 4000。

CHAR(n):长度固定为n的字串,n不能超过 254。

INTEGER: 值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,5,6,7,8.

REAL: 所有值都是浮动的数值,被存储为8字节的IEEE浮动标记序号.

TEXT: 值为文本字符串,使用数据库编码存储(TUTF-8, UTF-16BE or UTF-16-LE).

BLOB: 值是BLOB数据块,以输入的数据格式进行存储。如何输入就如何存储,不改  变格式。

DATA :包含了 年份、月份、日期。

TIME: 包含了 小时、分钟、秒。

相信学过数据库的童鞋对这些数据类型都不陌生的!!!!!!!!!!

二.SQLiteDatabase的介绍

Android提供了创建和是用SQLite数据库的API。SQLiteDatabase代表一个数据库对象,提供了操作数据库的一些方法。在 Android的SDK目录下有sqlite3工具,我们可以利用它创建数据库、创建表和执行一些SQL语句。下面是SQLiteDatabase的常用 方法。

SQLiteDatabase的常用方法

方法名称
方法表示含义
openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory  factory)
打开或创建数据库
insert(String table,String nullColumnHack,ContentValues  values)
插入一条记录
delete(String table,String whereClause,String[]  whereArgs)
删除一条记录
query(String table,String[] columns,String selection,String[]  selectionArgs,String groupBy,String having,String  orderBy)
查询一条记录
update(String table,ContentValues values,String whereClause,String[]  whereArgs)
修改记录
execSQL(String sql)
执行一条SQL语句
close()
关闭数据库

Google公司命名这些方法的名称都是非常形象的。例如openOrCreateDatabase,我们从字面英文含义就能看出这是个打开或创建数据库的方法。

1、打开或者创建数据库

在Android 中使用SQLiteDatabase的静态方法 openOrCreateDatabase(String  path,SQLiteDatabae.CursorFactory  factory)打 开或者创建一个数据库。它会自动去检测是否存在这个数据库,如果存在则打开,不存在则创建一个数据库;创建成功则返回一个SQLiteDatabase对 象,否则抛出异常FileNotFoundException。

下面是创建名为“stu.db”数据库的代码:
openOrCreateDatabase(String  path,SQLiteDatabae.CursorFactory  factory)
参数1  数据库创建的路径

参数2  一般设置为null就可以了

 

  1. db=SQLiteDatabase.openOrCreateDatabase(“/data/data/com.lingdududu.db/databases/stu.db”,null);  

2、创建表

创建一张表的步骤很简单:

  • 编写创建表的SQL语句
  • 调用SQLiteDatabase的execSQL()方法来执行SQL语句

下面的代码创建了一张用户表,属性列为:id(主键并且自动增加)、sname(学生姓名)、snumber(学号)

 

  1. private void createTable(SQLiteDatabase db){
  2. //创建表SQL语句
  3. String stu_table=“create table usertable(_id integer primary key autoincrement,sname text,snumber text)”;   
  4. //执行SQL语句
  5. db.execSQL(stu_table);
  6. }

3、插入数据
插入数据有两种方法:
①SQLiteDatabase的insert(String table,String nullColumnHack,ContentValues  values)方法,
参数1  表名称,
参数2  空列的默认值
参数3  ContentValues类型的一个封装了列名称和列值的Map;
②编写插入数据的SQL语句,直接调用SQLiteDatabase的execSQL()方法来执行
*种方法的代码:

 

  1. private void insert(SQLiteDatabase db){   
  2. //实例化常量值
  3. ContentValues cValue = new ContentValues();
  4. //添加用户名
  5. cValue.put(“sname”,”xiaoming”);   
  6. //添加密码
  7. cValue.put(“snumber”,”01005″);   
  8. //调用insert()方法插入数据   
  9. db.insert(“stu_table”,null,cValue);   
  10. }

第二种方法的代码:

 

  1. private void insert(SQLiteDatabase db){   
  2. //插入数据SQL语句
  3. String stu_sql=“insert into stu_table(sname,snumber) values(‘xiaoming’,’01005′)”;   
  4. //执行SQL语句
  5. db.execSQL(sql);
  6. }

4、删除数据

删除数据也有两种方法:

①调用SQLiteDatabase的delete(String table,String whereClause,String[]  whereArgs)方法
参数1  表名称
参数2  删除条件
参数3  删除条件值数组

②编写删除SQL语句,调用SQLiteDatabase的execSQL()方法来执行删除。

*种方法的代码:

 

  1. private void delete(SQLiteDatabase db) {   
  2. //删除条件
  3. String whereClause = “id=?”;   
  4. //删除条件参数
  5. String[] whereArgs = {String.valueOf(2)};
  6. //执行删除
  7. db.delete(“stu_table”,whereClause,whereArgs);   
  8. }

第二种方法的代码:

 

  1. private void delete(SQLiteDatabase db) {   
  2. //删除SQL语句
  3. String sql = “delete from stu_table where _id = 6”;   
  4. //执行SQL语句
  5. db.execSQL(sql);
  6. }

5、修改数据

修改数据有两种方法:

①调用SQLiteDatabase的update(String table,ContentValues values,String  whereClause, String[]  whereArgs)方法
参数1  表名称
参数2  跟行列ContentValues类型的键值对Key-Value
参数3  更新条件(where字句)
参数4  更新条件数组

②编写更新的SQL语句,调用SQLiteDatabase的execSQL执行更新。

*种方法的代码:

 

  1. private void update(SQLiteDatabase db) {   
  2. //实例化内容值 ContentValues values = new ContentValues();   
  3. //在values中添加内容   
  4. values.put(“snumber”,”101003″);   
  5. //修改条件
  6. String whereClause = “id=?”;   
  7. //修改添加参数
  8. String[] whereArgs={String.valuesOf(1)};
  9. //修改
  10. db.update(“usertable”,values,whereClause,whereArgs);   
  11. }

第二种方法的代码:

 

  1. private void update(SQLiteDatabase db){   
  2. //修改SQL语句
  3. String sql = “update stu_table set snumber = 654321 where id = 1”;   
  4. //执行SQL
  5. db.execSQL(sql);
  6. }

6、查询数据

在Android中查询数据是通过Cursor类来实现的,当我们使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor指向的就是每一条数据。它提供了很多有关查询的方法,具体方法如下:

public  Cursor query(String table,String[] columns,String selection,String[]  selectionArgs,String groupBy,String having,String orderBy,String limit);

各个参数的意义说明:

参数table:表名称

参数columns:列名称数组

参数selection:条件字句,相当于where

参数selectionArgs:条件字句,参数数组

参数groupBy:分组列

参数having:分组条件

参数orderBy:排序列

参数limit:分页查询限制

参数Cursor:返回值,相当于结果集ResultSet

Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法getString()等.

Cursor游标常用方法

方法名称
方法描述
getCount()
获得总的数据项数
isFirst()
判断是否*条记录
isLast()
判断是否*后一条记录
moveToFirst()
移动到*条记录
moveToLast()
移动到*后一条记录
move(int offset)
移动到指定记录
moveToNext()
移动到下一条记录
moveToPrevious()
移动到上一条记录
getColumnIndex(String  columnName)
根据列名称获得列索引
getInt(int columnIndex)
获得指定列索引的int类型值
getString(int columnIndex)
获得指定列缩影的String类型值

下面就是用Cursor来查询数据库中的数据,具体代码如下:

 

  1. private void query(SQLiteDatabase db) {
  2. //查询获得游标
  3. Cursor cursor = db.query (“usertable”,null,null,null,null,null,null);   
  4. //判断游标是否为空
  5. if(cursor.moveToFirst() {   
  6. //遍历游标
  7. for(int i=0;i<cursor.getCount();i++){   
  8. cursor.move(i);   
  9. //获得ID
  10. int id = cursor.getInt(0);   
  11. //获得用户名
  12. String username=cursor.getString(1);   
  13. //获得密码
  14. String password=cursor.getString(2);   
  15. //输出用户信息 System.out.println(id+“:”+sname+”:”+snumber);   
  16. }
  17. }
  18. }

 

第二种方法的代码:

 

 

 

  1. private void update(SQLiteDatabase db){   
  2. //修改SQL语句
  3. String sql = “select name frome uset_table while id = 65 group by id  having id<10 order by  “;   
  4. //执行SQL
  5. Cursor cursor =db.execSQL(sql);
  6. }

 

select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5

 

 

7、删除指定表
编写插入数据的SQL语句,直接调用SQLiteDatabase的execSQL()方法来执行

 

  1. private void drop(SQLiteDatabase db){   
  2. //删除表的SQL语句   
  3. String sql =“DROP TABLE stu_table”;   
  4. //执行SQL   
  5. db.execSQL(sql);
  6. }

三. SQLiteOpenHelper
该类是 SQLiteDatabase一个辅助类。这个类主要生成一  个数据库,并对数据库的版本进行管理。当在程序当中调用这个类的方法 getWritableDatabase()或者 getReadableDatabase()方法的时候,如果当时没有数据,那么Android系统就会自动生成一个数据库。 SQLiteOpenHelper 是一个抽象类,我们通常需要继承它,并且实现里面的3个函数:

1.onCreate(SQLiteDatabase)

在数据库*次生成的时候会调用这个方法,也就是说,只有在创建数据库的时候才会调用,当然也有一些其它的情况,一般我们在这个方法里边生成数据库表。

2.  onUpgrade(SQLiteDatabase,int,int)
当数据库需要升级的时候,Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表,并建立新的数据表,当然是否还需要做其他的操作,完全取决于应用的需求。

3.  onOpen(SQLiteDatabase):

这是当打开数据库时的回调函数,一般在程序中不是很常使用。

写了这么多,改用用实际例子来说明上面的内容了。下面这个操作数据库的实例实现了创建数据库,创建表以及数据库的增删改查的操作。
该实例有两个类:
com.lingdududu.testSQLite 调试类
com.lingdududu.testSQLiteDb  数据库辅助类

SQLiteActivity.java

 

  1. package com.lingdududu.testSQLite;  
  2. import com.lingdududu.testSQLiteDb.StuDBHelper;  
  3. import android.app.Activity;  
  4. import android.content.ContentValues;  
  5. import android.database.Cursor;  
  6. import android.database.sqlite.SQLiteDatabase;  
  7. import android.os.Bundle;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. /* 
  12. * @author lingdududu 
  13. */  
  14. public class SQLiteActivity extends Activity {  
  15. /** Called when the activity is first created. */  
  16. //声明各个按钮  
  17. private Button createBtn;  
  18. private Button insertBtn;  
  19. private Button updateBtn;  
  20. private Button queryBtn;  
  21. private Button deleteBtn;  
  22. private Button ModifyBtn;  
  23. @Override  
  24. public void onCreate(Bundle savedInstanceState) {  
  25. super.onCreate(savedInstanceState);  
  26. setContentView(R.layout.main);
  27. //调用creatView方法  
  28. creatView();
  29. //setListener方法  
  30. setListener();
  31. }
  32. //通过findViewById获得Button对象的方法  
  33. private void creatView(){  
  34. createBtn = (Button)findViewById(R.id.createDatabase);
  35. updateBtn = (Button)findViewById(R.id.updateDatabase);
  36. insertBtn = (Button)findViewById(R.id.insert);
  37. ModifyBtn = (Button)findViewById(R.id.update);
  38. queryBtn = (Button)findViewById(R.id.query);
  39. deleteBtn = (Button)findViewById(R.id.delete);
  40. }
  41. //为按钮注册监听的方法  
  42. private void setListener(){  
  43. createBtn.setOnClickListener(new CreateListener());  
  44. updateBtn.setOnClickListener(new UpdateListener());  
  45. insertBtn.setOnClickListener(new InsertListener());  
  46. ModifyBtn.setOnClickListener(new ModifyListener());  
  47. queryBtn.setOnClickListener(new QueryListener());  
  48. deleteBtn.setOnClickListener(new DeleteListener());  
  49. }
  50. //创建数据库的方法  
  51. class CreateListener implements OnClickListener{  
  52. @Override  
  53. public void onClick(View v) {  
  54. //创建StuDBHelper对象  
  55. StuDBHelper dbHelper = new StuDBHelper(SQLiteActivity.this,“stu_db”,null,1);  
  56. //得到一个可读的SQLiteDatabase对象  
  57. SQLiteDatabase db =dbHelper.getReadableDatabase();
  58. }
  59. }
  60. //更新数据库的方法  
  61. class UpdateListener implements OnClickListener{  
  62. @Override  
  63. public void onClick(View v) {  
  64. // 数据库版本的更新,由原来的1变为2  
  65. StuDBHelper dbHelper = new StuDBHelper(SQLiteActivity.this,“stu_db”,null,2);  
  66. SQLiteDatabase db =dbHelper.getReadableDatabase();
  67. }
  68. }
  69. //插入数据的方法  
  70. class InsertListener implements OnClickListener{  
  71. @Override  
  72. public void onClick(View v) {  
  73. StuDBHelper dbHelper = new StuDBHelper(SQLiteActivity.this,“stu_db”,null,1);  
  74. //得到一个可写的数据库  
  75. SQLiteDatabase db =dbHelper.getWritableDatabase();
  76. //生成ContentValues对象 //key:列名,value:想插入的值   
  77. ContentValues cv = new ContentValues();  
  78. //往ContentValues对象存放数据,键-值对模式  
  79. cv.put(“id”, 1);  
  80. cv.put(“sname”, “xiaoming”);  
  81. cv.put(“sage”, 21);  
  82. cv.put(“ssex”, “male”);  
  83. //调用insert方法,将数据插入数据库  
  84. db.insert(“stu_table”, null, cv);  
  85. //关闭数据库  
  86. db.close();
  87. }
  88. }
  89. //查询数据的方法  
  90. class QueryListener implements OnClickListener{  
  91. @Override  
  92. public void onClick(View v) {  
  93. StuDBHelper dbHelper = new StuDBHelper(SQLiteActivity.this,“stu_db”,null,1);  
  94. //得到一个可写的数据库  
  95. SQLiteDatabase db =dbHelper.getReadableDatabase();
  96. //参数1:表名   
  97. //参数2:要想显示的列   
  98. //参数3:where子句   
  99. //参数4:where子句对应的条件值   
  100. //参数5:分组方式   
  101. //参数6:having条件   
  102. //参数7:排序方式   
  103. Cursor cursor = db.query(“stu_table”, new String[]{“id”,”sname”,”sage”,”ssex”}, “id=?”, new String[]{“1”}, null, null, null);  
  104. while(cursor.moveToNext()){  
  105. String name = cursor.getString(cursor.getColumnIndex(“sname”));  
  106. String age = cursor.getString(cursor.getColumnIndex(“sage”));  
  107. String sex = cursor.getString(cursor.getColumnIndex(“ssex”));  
  108. System.out.println(“query——->” + “姓名:”+name+” “+”年龄:”+age+” “+”性别:”+sex);  
  109. }
  110. //关闭数据库  
  111. db.close();
  112. }
  113. }
  114. //修改数据的方法  
  115. class ModifyListener implements OnClickListener{  
  116. @Override  
  117. public void onClick(View v) {  
  118. StuDBHelper dbHelper = new StuDBHelper(SQLiteActivity.this,“stu_db”,null,1);  
  119. //得到一个可写的数据库  
  120. SQLiteDatabase db =dbHelper.getWritableDatabase();
  121. ContentValues cv = new ContentValues();  
  122. cv.put(“sage”, “23”);  
  123. //where 子句 “?”是占位符号,对应后面的”1”,  
  124. String whereClause=“id=?”;  
  125. String [] whereArgs = {String.valueOf(1)};  
  126. //参数1 是要更新的表名  
  127. //参数2 是一个ContentValeus对象  
  128. //参数3 是where子句  
  129. db.update(“stu_table”, cv, whereClause, whereArgs);  
  130. }
  131. }
  132. //删除数据的方法  
  133. class DeleteListener implements OnClickListener{  
  134. @Override  
  135. public void onClick(View v) {  
  136. StuDBHelper dbHelper = new StuDBHelper(SQLiteActivity.this,“stu_db”,null,1);  
  137. //得到一个可写的数据库  
  138. SQLiteDatabase db =dbHelper.getReadableDatabase();
  139. String whereClauses = “id=?”;  
  140. String [] whereArgs = {String.valueOf(2)};  
  141. //调用delete方法,删除数据   
  142. db.delete(“stu_table”, whereClauses, whereArgs);  
  143. }
  144. }
  145. }

StuDBHelper.java

  1. package com.lingdududu.testSQLiteDb;  
  2. import android.content.Context;  
  3. import android.database.sqlite.SQLiteDatabase;  
  4. import android.database.sqlite.SQLiteDatabase.CursorFactory;  
  5. import android.database.sqlite.SQLiteOpenHelper;  
  6. import android.util.Log;  
  7. public class StuDBHelper extends SQLiteOpenHelper {  
  8. private static final String TAG = “TestSQLite”;  
  9. public static final int VERSION = 1;  
  10. //必须要有构造函数  
  11. public StuDBHelper(Context context, String name, CursorFactory factory,  
  12. int version) {  
  13. super(context, name, factory, version);  
  14. }
  15. // 当*次创建数据库的时候,调用该方法   
  16. public void onCreate(SQLiteDatabase db) {  
  17. String sql = “create table stu_table(id integer  primary  key autoincrement,sname varchar(20),sage integer,ssex varchar(10))”;  
  18. //输出创建数据库的日志信息  
  19. Log.i(TAG, “create Database————->”);  
  20. //execSQL函数用于执行SQL语句  
  21. db.execSQL(sql);
  22. }
  23. //当更新数据库的时候执行该方法  
  24. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  25. //输出更新数据库的日志信息  
  26. Log.i(TAG, “update Database————->”);  
  27. }
  28. }

main.xml

 

  1. <?xml version=“1.0” encoding=”utf-8″?>  
  2. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  
  3. android:orientation=“vertical”  
  4. android:layout_width=“fill_parent”  
  5. android:layout_height=“fill_parent”  
  6. >
  7. <TextView
  8. android:layout_width=“fill_parent”   
  9. android:layout_height=“wrap_content”   
  10. android:text=“@string/hello”  
  11. />
  12. <Button
  13. android:id=“@+id/createDatabase”  
  14. android:layout_width=“fill_parent”   
  15. android:layout_height=“wrap_content”   
  16. android:text=“创建数据库”  
  17. />
  18. <Button
  19. android:id=“@+id/updateDatabase”  
  20. android:layout_width=“fill_parent”   
  21. android:layout_height=“wrap_content”   
  22. android:text=“更新数据库”  
  23. />
  24. <Button
  25. android:id=“@+id/insert”  
  26. android:layout_width=“fill_parent”   
  27. android:layout_height=“wrap_content”   
  28. android:text=“插入数据”  
  29. />
  30. <Button
  31. android:id=“@+id/update”  
  32. android:layout_width=“fill_parent”   
  33. android:layout_height=“wrap_content”   
  34. android:text=“更新数据”  
  35. />
  36. <Button
  37. android:id=“@+id/query”  
  38. android:layout_width=“fill_parent”   
  39. android:layout_height=“wrap_content”   
  40. android:text=“查询数据”  
  41. />
  42. <Button
  43. android:id=“@+id/delete”  
  44. android:layout_width=“fill_parent”   
  45. android:layout_height=“wrap_content”   
  46. android:text=“删除数据”  
  47. />
  48. </LinearLayout>

 

 

 

 

1、sqlite数据库判断表是否存在得方法

 

  1. /判断数据库中的表是否存在
  2. 注意:DBInfo是表名      cmd.CommandText = “SELECT COUNT(*) FROM sqlite_master where type=’table’ and name=’DBInfo'”;  

 

sqlite 中判断某个表是否存在的方法,贴出来供大家参考(java 、android)

 

    1. public boolean tabbleIsExist(String tableName){  
    2.         boolean result = false;  
    3.         if(tableName == null){  
    4.                 return false;  
    5.         }
    6.         SQLiteDatabase db = null;  
    7.         Cursor cursor = null;  
    8.         try {  
    9.                 db = this.getReadableDatabase();  
    10.                 String sql = “select count(*) as c from “+AppConstant.DataBaseName+” where type =’table’ and name ='”+tableName.trim()+”‘ “;  
    11.                 cursor = db.rawQuery(sql, null);  
    12.                 if(cursor.moveToNext()){  
    13.                         int count = cursor.getInt(0);  
    14.                         if(count>0){  
    15.                                 result = true;  
    16.                         }
    17.                 }
    18.         } catch (Exception e) {  
    19.                 // TODO: handle exception  
    20.         }
    21.         return result;  
    22. }

 

程序运行的效果图:

%title插图%num

使用adb命令查看数据库:

1.在命令行窗口输入adb  shell回车,就进入了Linux命令行,现在就可以使用Linux的命令了。

2.ls回车,显示所有的东西,其中有个data。

3.cd data回车,再ls回车,cd  data回车,ls回车后就会看到很多的com…………….,那就是系统上的应用程序包名,找到你数据库程序的包名,然后进入。

4.进去后在查看所有,会看到有databases,进入databases,显示所有就会发现你的数据库名字,这里使用的是”stu_db”。

5.sqlite3 stu_db回车就进入了你的数据库了,然后“.schema”就会看到该应用程序的所有表及建表语句。

6.之后就可以使用标准的SQL语句查看刚才生成的数据库及对数据执行增删改查了。
注:ls,cd等命令都是linux的基本命令,不了解的同学可以看看有关这方面的资料。

下面介绍几个在SQLite中常用到的adb命令:

查看
.database 显示数据库信息;
.tables 显示表名称;
.schema 命令可以查看创建数据表时的SQL命令;
.schema table_name 查看创建表table_name时的SQL的命令;

插入记录
insert into table_name values (field1, field2, field3…);

查询
select * from table_name;查看table_name表中所有记录;
select * from table_name where field1=’xxxxx’; 查询符合指定条件的记录;

删除
drop table_name;     删除表;
drop index_name;     删除索引;
——————————————-查询,插入,删除等操作数据库的语句记得不要漏了;—————————————-

# sqlite3 stu_db
sqlite3 stu_db
SQLite version 3.6.22
Enter  “.help” for instructions
Enter SQL statements terminated with a  “;”
sqlite> .schema
.schema
CREATE TABLE  android_metadata (locale TEXT);
CREATE TABLE stu_table(id int,sname varchar(20),sage int,ssex  varchar(10));  —>创建的表
sqlite> select * from stu_table;
select * from  stu_table;
1|xiaoming|21|male
sqlite>

插入数据

sqlite> insert into stu_table  values(2,’xiaohong’,20,’female’);

插入的数据记得要和表中的属性一一对应
insert into stu_table  values(2,’xiaohong’,20,’female’);
sqlite> select * from  stu_table;
select * from  stu_table;
1|xiaoming|21|male
2|xiaohong|20|female   ————–> 插入的数据
sqlite>

当点击修改数据的按钮时候

sqlite> select * from stu_table;
select * from  stu_table;
1|xiaoming|23|male  ————–>年龄被修改为23
2|xiaohong|20|female
sqlite>

当点击删除数据的按钮

sqlite> select * from stu_table;
select * from  stu_table;
1|xiaoming|23|male        id=2的数据已经被删除

总之,我们可以在代码中执行数据库的增删改查,也可以在adb命令行下实现。不过因为SQLite没有客户端,不能直接的查看数据库变化后的信息,所以常用adb命令行查看数据库改变后的信息。

Android SQLite (一) 数据库简介

大家好,今天来介绍一下SQLite的相关知识,并结合Java实现对SQLite数据库的操作。

SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎。它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行。

SQLite由以下几个部分组成:SQL编译器、内核、后端以及附件。SQLite通过利用虚拟机和虚拟数据库引擎(VDBE),是调试、修改和扩 展SQLite的内核变得更加方便。所有SQL语句都被编译成易读的、可以在SQLite虚拟机中执行的程序集。SQLite的整体结构图如下:

%title插图%num

值得一提的是,袖珍型的SQLite竟然可以支持高达2TB大小的数据库,每个数据库都是以单个文件的形式存在,这些数据都是以B-Tree的数据结构形式存储在磁盘上。

在事务处理方面,SQLite通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一 个可以写入数据。在某个进程或线程想数据库执行写操作之前,必须获得独占锁。在获得独占锁之后,其他的读或写操作将不会再发生。

SQLite采用动态数据类型,当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值 转换成该列的类型,如果不能转换,则该值将作为本身的类型存储,SQLite称这为“弱类型”。但有一个特例,如果是INTEGER PRIMARY KEY,则其他类型不会被转换,会报一个“datatype missmatch”的错误。

概括来讲,SQLite支持NULL、INTEGER、REAL、TEXT和BLOB数据类型,分别代表空值、整型值、浮点值、字符串文本、二进制对象。

下面,我们就来亲自操作一下SQLite数据库。

在操作之前,朋友们要先下载SQLite数据库,官方的下载页面是http://sqlite.org/download.html, 我是在Windows下试验,所以我选择了Precompiled Binaries For Windows下面的sqlite-shell-win32-x86和sqlite-analyzer-win32-x86的zip包,前者是 SQLite数据库引擎,后者是SQLite数据库分析器,主要用于分析数据库的状态等信息,大家也可以根据自己的情况去下载。下载完成后分别解压,得到 两个可执行文件,如图:

%title插图%num

这两个文件可以根据自己的喜好放置在指定的位置,我将其放在D盘根目录下。下面我们就来一步一步操作SQLite:

创建数据库:

  1. D:\>sqlite3 test.db
  2. SQLite version 3.7.7.1 2011-06-28 17:39:05
  3. Enter “.help” for instructions  
  4. Enter SQL statements terminated with a “;”  
  5. sqlite> .databases
  6. seq  name             file  
  7. —  —————  ———————————————————-  
  8. 0    main             D:\test.db
  9. sqlite>

我 们执行了sqlite3命令,参数就是数据库的名称,如果该数据库已存在,则使用,如果不存在,则新建一个,这里我们简单的在当前位置创建了 test.db,你也可以在任何存在的并且可写的目录下创建自己的数据库。(如果对于SQLite的命令不太熟悉,可以执行“.help”命令列出所有的 命令清单进行查看)。

创建表:

  1. sqlite> CREATE TABLE person (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20), age SMALLINT);  
  2. sqlite> .tables
  3. person
  4. sqlite> .schema person  
  5. CREATE TABLE person (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20), age SMALLINT);  
  6. sqlite>

在我们创建表之后,可以用“.tables”命令去查看已有的表,用“.schema”命令去查看表的结构,如果后面没有表名做参数,则将会输出所有表的建表语句。

插入数据:

  1. sqlite> INSERT INTO person VALUES (NULL, ‘john’, 30);  
  2. sqlite> SELECT * FROM person;  
  3. 1|john|30

从.sql文件导入数据:

  1. sqlite> .read test.sql  
  2. sqlite> SELECT * FROM person;  
  3. 1|john|30
  4. 2|david|35
  5. 3|henry|40
  6. sqlite>

分析数据库使用状态:

  1. D:\>sqlite3_analyzer test.db
  2. /** Disk-Space Utilization Report For test.db  
  3. Page size in bytes……………….. 1024  
  4. Pages in the whole file (measured)…. 4  
  5. Pages in the whole file (calculated).. 4  
  6. Pages that store data…………….. 4          100.0%
  7. Pages on the freelist (per header)…. 0            0.0%  
  8. Pages on the freelist (calculated)…. 0            0.0%  
  9. Pages of auto-vacuum overhead……… 0            0.0%  
  10. Number of tables in the database…… 4  
  11. Number of indices………………… 0  
  12. Number of named indices…………… 0  
  13. Automatically generated indices……. 0
  14. Size of the file in bytes…………. 4096  
  15. Bytes of user payload stored………. 39           0.95%  

备份数据库:

备份 SQLite 数据库有两种方法。如果数据库正在使用中,则应从命令行界面使用 .dump 命令。这样可以创建一个包含必要命令和数据的文件,从而重新创建数据库。.dump 命令也可以用于备份数据库表。

  1. sqlite> .dump
  2. PRAGMA foreign_keys=OFF;  
  3. BEGIN TRANSACTION;  
  4. CREATE TABLE person (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20), age SMALLINT);  
  5. INSERT INTO “person” VALUES(1,’john’,30);  
  6. INSERT INTO “person” VALUES(2,’david’,35);  
  7. INSERT INTO “person” VALUES(3,’henry’,40);  
  8. DELETE FROM sqlite_sequence;  
  9. INSERT INTO “sqlite_sequence” VALUES(‘person’,3);  
  10. COMMIT;  
  11. sqlite> .output dump.sql  
  12. sqlite> .dump
  13. sqlite>

我们可以指定输出的目标为一个文件,然后再使用命令时,输出信息就会写入指定的文件,如果想恢复为标准输出,可以这样设定:

  1. sqlite> .output stdout  
  2. sqlite> .dump
  3. PRAGMA foreign_keys=OFF;  
  4. BEGIN TRANSACTION;  
  5. CREATE TABLE person (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20), age SMALLINT);  
  6. INSERT INTO “person” VALUES(1,’john’,30);  
  7. INSERT INTO “person” VALUES(2,’david’,35);  
  8. INSERT INTO “person” VALUES(3,’henry’,40);  
  9. DELETE FROM sqlite_sequence;  
  10. INSERT INTO “sqlite_sequence” VALUES(‘person’,3);  
  11. COMMIT;  
  12. sqlite>

如果数据库没有处于使用状态,则可以直接将数据库文件复制到安全位置。

*后,我们可以使用“.quit”或“.exit”退出SQLite。

管理工具:

现在网络上的SQLite管理工具很多,我向大家推荐一款好用的工具:SQLite Expert。

%title插图%num

在Java中使用SQLite:

我们要想在Java中使用SQLite,需要下载SQLite相关驱动,推荐大家到http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC页面去下载*新的驱动包,现在*新版本是sqlite-jdbc-3.7.2.jar,体积有点大,因为它包含了Linux、Mac、Windows的本地类库,如图:

%title插图%num

下载了驱动之后,我们新建一个项目,名为sqlite:

%title插图%num

在上图中,我们引入sqlite驱动包到类路径下,然后建立一个db的文件夹,用于放置数据库文件。*后我们看一下Test.java代码:

  1. package com.scott.sqlite;  
  2. import java.sql.Connection;  
  3. import java.sql.DriverManager;  
  4. import java.sql.ResultSet;  
  5. import java.sql.Statement;  
  6. public class Test {  
  7.     public static void main(String[] args) throws Exception {  
  8.         Class.forName(“org.sqlite.JDBC”);  
  9.         Connection conn = DriverManager.getConnection(“jdbc:sqlite:db/test.db”);  
  10.         Statement stmt = conn.createStatement();
  11.         stmt.executeUpdate(“DROP TABLE IF EXISTS person”);  
  12.         stmt.executeUpdate(“CREATE TABLE person(id INTEGER, name STRING)”);  
  13.         stmt.executeUpdate(“INSERT INTO person VALUES(1, ‘john’)”);  
  14.         stmt.executeUpdate(“INSERT INTO person VALUES(2, ‘david’)”);  
  15.         stmt.executeUpdate(“INSERT INTO person VALUES(3, ‘henry’)”);  
  16.         ResultSet rs = stmt.executeQuery(“SELECT * FROM person”);  
  17.         while (rs.next()) {  
  18.             System.out.println(“id=>” + rs.getInt(“id”) + “, name=>” + rs.getString(“name”));  
  19.         }
  20.         stmt.close();
  21.         conn.close();
  22.     }
  23. }

执行Test.java文件,结果如下:

%title插图%num

这个时候,在我们的db目录下,就生成了一个test.db的文件:

%title插图%num

SQLite使用须知:

目前没有可用于 SQLite 的网络服务器。从应用程序运行位于其他计算机上的 SQLite 的惟一方法是从网络共享运行。这样会导致一些问题,像 UNIX® 和 Windows® 网络共享都存在文件锁定问题。还有由于与访问网络共享相关的延迟而带来的性能下降问题。

SQLite 只提供数据库级的锁定。

SQLite 没有用户帐户概念,而是根据文件系统确定所有数据库的权限。

结束语:

由于资源占用少、性能良好和零管理成本,嵌入式数据库有了它的用武之地,像Android、iPhone都有内置的SQLite数据库供开发人员使用,它的易用性可以加快应用程序的开发,并使得复杂的数据存储变得轻松了许多

使用SQLiteOpenHelper的onUpgrade实现数据库版本升级

Andoird的SQLiteOpenHelper类中有一个onUpgrade方法。帮助文档中只是说当数据库升级时该方法被触发。经过实践,解决了我一连串的疑问:

1. 帮助文档里说的“数据库升级”是指什么?

你开发了一个程序,当前是1.0版本。该程序用到了数据库。到1.1版本时,你在数据库的某个表中增加了一个字段。那么软件1.0版本用的数据库在软件1.1版本就要被升级了。

2. 数据库升级应该注意什么?

软件的1.0版本升级到1.1版本时,老的数据不能丢。那么在1.1版本的程序中就要有 地方能够检测出来新的软件版本与老的数据库不兼容,并且能够有办法把1.0软件的数据库升级到1.1软件能够使用的数据库。换句话说,要在1.0软件的数 据库的那个表中增加那个字段,并赋予这个字段默认值。

3. 程序如何知道数据库需要升级?

SQLiteOpenHelper类的构造函数有一个参数是int version,它的意思就是指数据库版本号。比如在软件1.0版本中,我们使用SQLiteOpenHelper访问数据库时,该参数为1,那么数据库版本号1就会写在我们的数据库中。

到了1.1版本,我们的数据库需要发生变化,那么我们1.1版本的程序中就要使用一个大于1的整数来构造SQLiteOpenHelper类,用于访问新的数据库,比如2。

当我们的1.1新程序读取1.0版本的老数据库时,就发现老数据库里存储的数据库版本是1,而我们新程序访问它时填的版本号为2,系统就知道数据库需要升级。

4. 何时触发数据库升级?如何升级?

当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。根据上述场景,在这个函数中把老版本数据库的相应表中增加字段,并给每条记录增加默认值即可。

新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。

升级完成后,数据库会自动存储*新的版本号为当前数据库版本号。

 

 

案例:

 

 

2013年4月,我们*次 发布了 我们的应用,数据库版本是1。

2013年5月,我们第二次 发布了 我们的应用,数据库版本是2。由于业务需要,我们更改了数据库里的某个表的表结构。

这时候就有这样的难题出现:

有些用户已经下载了4月份的版本1,并且已经使用了,很多数据存储在数据库了,这个时候,他想安装新的版本2,怎么办? 怎么才能让数据不丢失?

有的用户直接装了5月份的版本,那这些用户就直接使用了新的表结构格式。

可能以后还有版本3,4,N,怎么保证“数据不丢失的情况下“让用户手机里的数据库跟着升级?

——

我们记得SQLiteOpenHelper的onUpgrade方法,那么它是如何工作呢?我们该如何使用他?下面先说说使用它的方式。

解决方案:

我们在4月份数据库建立时,使用下面的方式

package dome.file.com.filedome;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Created by lidaqiang on 17/1/5.
 */
public class MyDbHelper1 extends SQLiteOpenHelper {
    public final static int DB_VERSION = 1;   
    public final static String DB_NAME = "mydb.db";
    public final String TABLE_NAME = "tbl_data";
    public final String COL_UID = "uid";
    public final String COL_ITSVALUE = "itsvalue";
    public final String COL_CREATEDDATE = "createddate";
    public final String COL_DESC = "desc";

    public MyDbHelper1(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table ["+TABLE_NAME+"] ( [uid] int identity primary key,[itsvalue] nvarchar(200),createddate TIMESTAMP default (datetime('now', 'localtime')) )";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

%title插图%num

我们注意看下数据库的版本

%title插图%num

…………………………

于是到了五月份,由于业务需要,我们想添加新的字段到这个表里。我们这样写代码:

package dome.file.com.filedome;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Created by lidaqiang on 17/1/5.
 */
public class MyDbHelper extends SQLiteOpenHelper {
    public final static int DB_VERSION = 2;    //版本号升级为2
    public final static String DB_NAME = "mydb.db";
    public final String TABLE_NAME = "tbl_data";
    public final String COL_UID = "uid";
    public final String COL_ITSVALUE = "itsvalue";
    public final String COL_CREATEDDATE = "createddate";
    public final String COL_DESC = "desc";

    public MyDbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //如果以前没有数据库,现在创建新的数据库时已经有新列desc了。  
        String sql = "create table [" + TABLE_NAME + "] ( [uid] int identity primary key,[itsvalue] nvarchar(200),createddate TIMESTAMP default (datetime('now', 'localtime')),[desc] nvarchar(300) )";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (oldVersion == 1 && newVersion == 2) {
            //从版本1到版本2时,增加了一个字段 desc         
            String sql = "alter table [" + TABLE_NAME + "] add [desc] nvarchar(300)";
            db.execSQL(sql);
        }
    }
}

这个时候,onCreate方法里,是新的建立表的方式。而不同的是 onUpgrade方法里我们检测了这样的变化,如果 是从版本1到版本2,我们执行了一段”添加列的sql语句“。这段代码,仅仅在符合这样的场景里执行。

通过上面的方式,我们就完成了一次的数据库升级的操作。Android会判断 数据库的版本号,并自动的调用onUpgrade方法。

%title插图%num

看看数据库的版本

%title插图%num

——————

下面是一些扩展内容?

我们通过SQLite Expert看到的这个user_version是什么东西?经过在网络上反复查到资料,这个其实是sqlite数据库的”PRAGMA “.

看看描述:

<span style="font-size: 15px;"><strong>PRAGMA schema_version;
PRAGMA schema_version = integer ;
PRAGMA user_version;
PRAGMA user_version = integer ;</strong></span>
The pragmas schema_version and user_version are used to set or get the value of the schema-version and user-version, respectively. The schema-version and the user-version are big-endian 32-bit signed integers stored in the database header at offsets 40 and 60, respectively.
The schema-version is usually only manipulated internally by SQLite. It is incremented by SQLite whenever the database schema is modified (by creating or dropping a table or index). The schema version is used by SQLite each time a query is executed to ensure that the internal cache of the schema used when compiling the SQL query matches the schema of the database against which the compiled query is actually executed. Subverting this mechanism by using "PRAGMA schema_version" to modify the schema-version is potentially dangerous and may lead to program crashes or database corruption. Use with caution!
The user-version is not used internally by SQLite. It may be used by applications  for any purpose.

在数据库中,我们可以使用这样写 sql语句来查询它:

PRAGMA main.user_version

或者来设置它的值

PRAGMA main.user_version = 1

更多内容参考sqlite的官方描述。

安卓下视频压缩和转换格式的问题

安卓下视频压缩和转换格式的问题

 

wobuhuicode · 6 小时 30 分钟前 · 472 次点击

安卓下调用 ffmpeg 来压缩视频,转换视频格式。
而 ios 下使用自带的 API 来达到同样效果。
30 s 视频,安卓基本需要 30 s 来完成,
而 ios 只需要 3 秒不到。

有什么办法可以提高安卓下的速度?

7 条回复    2021-08-16 14:38:14 +08:00

minami
    1

minami   6 小时 11 分钟前

ffmpeg 不支持 mediacodec 硬编码,自己基于 ffmpeg 封装一个,或者不使用 ffmpeg 直接调用 mediacodec
moonkiller
    2

moonkiller   5 小时 53 分钟前

iOS 速度快难道不是 iPhone 硬件的功劳吗?
M1 重点还展示了自家的视频剪辑导出能力
youxiachai
    3

youxiachai   5 小时 32 分钟前

这是解码器的问题了啊…..得看你手上的安卓能支持啥硬解了..
rosu
    4

rosu   5 小时 21 分钟前 via Android

@minami ffmpeg 支持 mediacodec 哦。
WebKit
    5

WebKit   5 小时 11 分钟前 via Android

android 用 mediacodec 相关的 API 啊
minami
    6

minami   4 小时 20 分钟前

@rosu 仔细看看 ffmpeg 文档,只支持解码哦
wobuhuicode
    7

wobuhuicode   3 小时 14 分钟前

mediacodec 兼容性太差了。还是使用 ffmpeg 安全一点。

来推荐几本对职业生涯影响较大的技术书籍

开发过程中,有时候会觉得当时要是没有读过那本书,现在肯定想不到要这样做。由此可以推定,因为曾经没有读过某一本书,会导致想不到要怎样做。所以不如大家都相互推荐一下自己读过的好书,拓宽自己的知识领域。

我先推荐几本对我影响比较大的书:

《算法》基本功,理解常用的组件的原理,比如 redis 。 面试也很有用

《 Head First 设计模式(中文版)》业务开发利器。可以写出更优雅的代码

《 MySQL 技术内幕》充分理解 mysql,每次阅读都有新收获

《 Go 语言设计与实现》 深入了解 golang 。 面试也很有用

《架构整洁之道》 如何避免代码不断膨胀导致项目不可维护,非常有效

85 条回复    2021-08-16 15:57:38 +08:00

mazhimazh
    1

mazhimazh   1 天前   ❤️ 73

对我影响比较大的书《深入解析 Java 编译器:源码剖析与实例详解》《深入剖析 Java 虚拟机:源码剖析与实例详解》,为什么对我影响比较大呢?因为是我写的
youjianchuiyan
    2

youjianchuiyan   1 天前

《 unix 网络编程》
musi
    3

musi   1 天前

来推荐几本爱民老师的书
《程序原本》
《我的架构思想》
letianqiu
    4

letianqiu   1 天前

@mazhimazh 《深入剖析 Java 虚拟机:源码剖析与实例详解》预计什么时候上市?
SearchDream
    5

SearchDream   1 天前 via iPhone

TCP/IP 详解
xylxAdai
    6

xylxAdai   1 天前   ❤️ 6

《深入理解计算机系统》,我觉得每个学习计算机的都应该看一下。
HENQIGUAI
    7

HENQIGUAI   1 天前

《程序员之禅》《禅与摩托车维修艺术》《黑客与画家》
milkleeeeee
    8

milkleeeeee   1 天前

我来个不那么高大上的……大学的时候买了本《 JavaScript 权威指南(第六版)》自学,从此开始了前端职业生涯。
mazhimazh
    9

mazhimazh   1 天前

@letianqiu 这个月底吧,估计
bug403
    10

bug403   1 天前

没那末大影响,一本小说 《疯狂的程序员》*影 讲外 @挂

agagega
    11

agagega   1 天前 via iPhone

《疯狂的程序员》
《 C++简明教程》
《 C++沉思录》
《编码》
《程序员修炼之道》
《 UNIX 编程艺术》

CrazyRundong
    12

CrazyRundong   1 天前 via iPhone

应该是大二时看的《 MATLAB 在数学建模中的应用》,觉醒了内心的程序员之魂 (bushi),随后开启了数学建模-推荐系统-xgboost-传统 cv-人工智障的升级打怪之路
btnokami
    13

btnokami   1 天前 via iPhone   ❤️ 2

Design Data Intensive Application,真的神书
codyfeng
    14

codyfeng   1 天前 via Android

Effective C++
More Effective C++
shiny
    15

shiny   1 天前

UNIX 环境高级编程:服务器环境不再神秘
重来:开启了对工作方法的思考,启蒙
禅与摩托车维修艺术:始于技术,超脱技术细节,思考哲学问题
Hallelu
    16

Hallelu   1 天前

@mazhimazh 哈哈哈哈哈哈 有被装到
letianqiu
    17

letianqiu   23 小时 44 分钟前

@mazhimazh 到时候会支持一下。
Pagliacii
    18

Pagliacii   23 小时 41 分钟前   ❤️ 1

SICP
ruchee
    19

ruchee   22 小时 12 分钟前

《精通正则表达式(第三版)》:读一遍此书,写正则手到擒来,再也不用到处复制粘贴
xiaket
    20

xiaket   22 小时 7 分钟前

Pro Django
wandehul
    21

wandehul   21 小时 45 分钟前   ❤️ 1

<<知音>><<故事会>>难道不配拥有姓名吗
qping
    22

qping   21 小时 42 分钟前

@milkleeeeee #8 作为一个后端,看了 javascript 设计模式 ,觉得大有收益
Cbdy
    23

Cbdy   21 小时 42 分钟前 via Android

Unix 编程艺术
Issacx
    24

Issacx   21 小时 37 分钟前

我加一本《 Thinking in Java 》,从这里我开始理解面向对象编程。
enGrave93
    25

enGrave93   21 小时 34 分钟前 via Android

《 Java 并发编程之美》,《 Android 开发艺术探索》,《算法(第 4 版)》
feather12315
    26

feather12315   17 小时 55 分钟前 via Android

@ruchee #19 读完了也忘光了。

程序员的自我修养、Linux 高级环境编程、Linux Inside 、Intel 微处理器 /计算机组成原理、龙书。

feather12315
    27

feather12315   17 小时 54 分钟前 via Android

@ruchee #19 强推 regex101.com ,有了这个才是手到擒来
csfreshman
    28

csfreshman   17 小时 52 分钟前

UNIX 高级环境编程 和 SICP,大三 大四啃了一年,以为自己看懂了,工作后常伴左右温故知新
morty0
    29

morty0   17 小时 42 分钟前

designing data-intensive applications
MeatIndustry
    30

MeatIndustry   17 小时 20 分钟前 via iPhone

收集一波大家的神书…
Arthurccc
    31

Arthurccc   17 小时 1 分钟前

好贴。希望大家踊跃。
WangTx1996
    32

WangTx1996   17 小时 0 分钟前 via iPhone

SICP 和 CSAPP
chevalier
    33

chevalier   16 小时 38 分钟前

《黑客与画家》
《构建高性能 Web 站点》郭欣
《 C Primer Plus 》 Stephen Prata
《 Go 预言学习笔记》雨痕
katsusan
    34

katsusan   16 小时 33 分钟前

CSAPP+APUE+DDIA
aguesuka
    35

aguesuka   16 小时 22 分钟前

“The HoTT Bokk”
levelworm
    36

levelworm   15 小时 15 分钟前 via Android

@mazhimazh 大佬能不能说一说学习和工作的经历?感觉很多人虽然有很久的工作经验,但是技术上并没有多少提高。
NetCobra
    37

NetCobra   12 小时 12 分钟前   ❤️ 1

《人月神话》
《代码整洁之道》
chenyu0532
    38

chenyu0532   9 小时 32 分钟前

算法 head first 设计模式 + 若干本设计模式的书 代码整洁之道。
可能我的业务比较简单吧,我越来越觉得设计模式*重要,算法知道怎么回事就行了,在面试中比较有用 。
whywaoxaks
    39

whywaoxaks   9 小时 24 分钟前

小时候家里书架上的 谭浩强的《 basic 语言》。。
没这本书,估计不会对编程感兴趣。。
acerlawson
    40

acerlawson   9 小时 22 分钟前 via iPhone

CSAPP+OSTEP+CA:AQA
tonzeng
    41

tonzeng   9 小时 0 分钟前

《从删库到跑路》.jpg
xin053
    42

xin053   8 小时 42 分钟前

《软件调试》
BrainOnline
    43

BrainOnline   8 小时 42 分钟前

《陈景润传》
BrainOnline
    44

BrainOnline   8 小时 40 分钟前

#43 小学时候读的这本书,然后开启自己对数学的兴趣,否则之前是偏文科一些。
ffLoveJava
    45

ffLoveJava   8 小时 37 分钟前

先 Mark 一下 过会我在=商场
Rebely
    46

Rebely   8 小时 34 分钟前

流畅的 python
mazhimazh
    47

mazhimazh   8 小时 34 分钟前

@levelworm 我工作也其实接近 10 年了吧,前 6 年都是做计算广告的,本来打算把计算广告的业务走通,后来觉得个人的性格不适合做业务,适合做技术,所以职业规划就变为了走技术,精通一个点了,下定决心研究虚拟机,为了让学习有产出就写了 2 本书,现在也做虚拟机相关工作,所以说只要决定了,就要好好准备,等机会来了就能抓住上车了
yunyuyuan
    48

yunyuyuan   8 小时 33 分钟前

《如何讨取富婆欢心》
zjj19950716
    49

zjj19950716   8 小时 29 分钟前

代码大全
coldmonkeybit
    50

coldmonkeybit   8 小时 27 分钟前

应该是《操作系统导论》,我非科班
necodba
    51

necodba   8 小时 26 分钟前

金鳞岂是池中物…
wangxn
    52

wangxn   8 小时 25 分钟前 via Android

深入浅出 MFC
深入 C++ 对象模型
前者入门,后者深入。都是侯捷写的或者翻译的书。
raptor
    53

raptor   8 小时 25 分钟前

Modern C++ Design: 看了半本决定放弃用了十来年的 C++,因为觉得这样的 C++不是我想要的,不是我玩它,是它玩我,后来改用 Python 十几年,表示还是这个好。

其它影响比较大的就是《人月神话》《人件》《软件需求》这类。

Longerrrr
    54

Longerrrr   8 小时 24 分钟前

编码
searene
    55

searene   8 小时 24 分钟前

Designing Data-Intensive Applications
nspih
    56

nspih   8 小时 13 分钟前

脊椎康复指南
mazhimazh
    57

mazhimazh   8 小时 9 分钟前

《如何与产品经理友好相处》
xhldtc
    58

xhldtc   7 小时 58 分钟前

对人生影响较大的书籍:《英雄志》
gaodq
    59

gaodq   7 小时 47 分钟前

《数据密集型应用系统设计》
https://book.douban.com/subject/30329536/
shanghai1943
    60

shanghai1943   7 小时 46 分钟前

《代码整洁之道》 《黑客与画家》《 程序员的修炼之道:从小工到专家 》《 Eeffective java 》
abc635073826
    61

abc635073826   7 小时 38 分钟前

《如何活到 80 岁》《如何活到 90 岁》《如何比别人活的长》
weiwenhao
    62

weiwenhao   7 小时 30 分钟前

《代码整洁之道》《计算机程序的构造与解释》《球状闪电》《凡人修仙传》
chigeyaowaner
    63

chigeyaowaner   7 小时 28 分钟前

《 程序员的修炼之道:从小工到专家 》+1,这本改变了我很多,每次搬家还要带着走。第二版比*版的内容做了一些扩充,*版有些内容在第二版里做了删减。无论是曳光弹还是简单设计等等,都很受用,也很经典,现在还会推荐给我的学弟学妹们。
不想看书的还可以看视频,有些内容讲的还是很不错的: https://www.zentao.net/redirect-index-19380.html,唯一的不足就是视频输出频率快,经常需要按暂停。个人还是希望书籍看完再看一些视频或者一些点评。

还有一本《代码整洁之道》,讲了很多关于代码整洁的重要性和实践,还给出了一些工具,只要遵循这些规则,就能编写出干净的代码,从而有效提升代码质量。这本书也是及其推荐的一本。

viator42
    64

viator42   7 小时 25 分钟前

「吃掉那只青蛙 : 拒*穷忙,把时间留给*重要的事」
4771314
    65

4771314   7 小时 23 分钟前   ❤️ 1

《颈椎病康复指南》
RudyS
    66

RudyS   7 小时 21 分钟前

Ayn Rand: 《源泉》《理想》《阿特拉斯耸耸肩》
silently9527
    67

silently9527   7 小时 12 分钟前

《程序员健康指南》《 MySQL 是怎样运行的 : 从根儿上理解 MySQL 》《算法第四版》
silently9527
    68

silently9527   7 小时 8 分钟前   ❤️ 1

《全国富婆通讯录》
meshell
    69

meshell   7 小时 8 分钟前

代码大全
0xZhangKe
    70

0xZhangKe   6 小时 50 分钟前

重构 /改善既有代码设计
Loserzhu
    71

Loserzhu   6 小时 38 分钟前

csapp
yutonliu
    72

yutonliu   6 小时 37 分钟前

前列腺养生保健
lovedebug
    73

lovedebug   6 小时 37 分钟前

技术科普书籍 《信息简史》
yingo
    74

yingo   6 小时 21 分钟前

apue,这本书直接看出快感来了..
Brentwans
    75

Brentwans   6 小时 11 分钟前

《谭浩强 c 语言程序设计》无出其右
TUNGH
    76

TUNGH   6 小时 6 分钟前

@mazhimazh 递茶
huZhao
    77

huZhao   5 小时 45 分钟前   ❤️ 1

《颈椎病的预防》,《一本书读懂颈椎病》,《痔疮》,《近视眼》,《减肥》,《如何比别人活的长》
tonghuashuai
    78

tonghuashuai   5 小时 25 分钟前

《 Redis 设计与实现》 – 当时在通勤的地铁上花了几天看完的,现在想想这本书真的是简单易懂读起来没有压力但又干货满满的一本小书
chairuosen
    79

chairuosen   5 小时 3 分钟前

代码大全
zhoudaiyu
    80

zhoudaiyu   4 小时 21 分钟前   ❤️ 1

运维向:
1 、Kubernetes in Action (顾名思义,讲 K8S 的,深入浅出,没有生硬的感觉,我的 K8S 入门书。马上出第二版了)
2 、Systems Performance – Enterprise and the Cloud (讲了一些 Linux 下的性能调优的,还有一些监控工具的,很不错)
3 、Fluent Python ( Python 进阶了,当初刚做运维学了几个月 Python 我就飘了,然后看了这本书仿佛觉得我学了假的 Python,第二本的英文版已经可以在 Safari 上看了)
4 、Wireshark 网络分析就这么简单(运维不懂网络有点说不过去了,这本书直接从例子入手讲一些网络的知识,推荐)
Phariel
    81

Phariel   4 小时 14 分钟前

我*近在看这本
编码:隐匿在计算机软硬件背后的语言

对于信息通讯产业人士比较有帮助

Klingon
    82

Klingon   4 小时 9 分钟前

严肃诚恳的推荐《荀子·劝学》
wzxlovesy
    83

wzxlovesy   3 小时 32 分钟前 via Android

OSTEP
naruco
    84

naruco   2 小时 14 分钟前

在没有扎实基础的前提下,于引擎搜索各类奇技淫巧都是在浪费时间;
我就是个例子,表面上解决了很多问题,实际狗屁不通。
《荀子·劝学》 +1
看了几句,甚好!
fkdtz
    85

fkdtz   1 小时 49 分钟前

《编码 : 隐匿在计算机软硬件背后的语言》

写了 N 年代码之后偶然看到这本书,让我认识到原来之前一直都在计算机的门外徘徊,这本书让我摸到了计算机的大门 。

这本书让人从信息的本质去思考:写这么多代码,归根结底是在干嘛?

Regular Expression 为何会翻译成正则表达式,而不是规则表达式

Regular Expression 为何会翻译成正则表达式,而不是规则表达式

 

kinboy · 9 小时 44 分钟前 via Android · 3141 次点击

一直对正则二字的含义不理解,所以去查了下,原来是古汉语词汇,意为:常规,规则

以下是百度百科的引用

正则是一个汉语词汇,拼音为 zhèng zé,基本意思是正其*仪法则;正规;常规;正宗等。出自《楚辞·离骚》、《插图本中国文学史》、《东京赋》等文献。

那么为什么当初不翻译成更加浅显易懂的规则表达式呢?

44 条回复    2021-08-16 16:18:28 +08:00

feather12315
    1

feather12315   9 小时 0 分钟前 via Android

还有个翻译:正规表达式
IgniteWhite
    2

IgniteWhite   8 小时 55 分钟前

https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F#%E8%AD%AF%E5%90%8D%E5%95%8F%E9%A1%8C

Regular Expression 的 Regular 一般被譯為正则、正规或常規。此處的 Regular 即是規則、規律的意思,Regular Expression 即「描述某種規則的表達式」之意。

jorneyr
    3

jorneyr   8 小时 48 分钟前   ❤️ 7

翻译为正则,首先没错,二是翻译的人文学素养比你的建议强很多。
silkriver
    4

silkriver   8 小时 43 分钟前

汉语词汇丰富,各种写法通常也能让人秒懂,*终确定规范时基本上就是看谁定的词接受度更高一点
weixiangzhe
    5

weixiangzhe   8 小时 43 分钟前 via iPhone   ❤️ 4

可能是我文学素养 确实太低了,好多英文我看懂了中文还是没有看懂吧
weixiangzhe
    6

weixiangzhe   8 小时 38 分钟前

x(?=y) 先行断言 Lookahead assertion: (positive lookahead) Matches “x” only if “x” is followed by “y”. For example, /Jack(?=Sprat)/ matches “Jack” only if it is followed by “Sprat”. `/Jack(?=Sprat
x(?!y) 正向否定查找 Negative lookahead assertion: Matches “x” only if “x” is not followed by “y”. For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. /\d+(?!\.)/.exec(‘3.141’) matches “141” but not “3”.
(?<=y)x 后行断言 Lookbehind assertion: Matches “x” only if “x” is preceded by “y”. For example, /(?<=Jack)Sprat/ matches “Sprat” only if it is preceded by “Jack”. `/(?<=Jack
(?<!y)x 反向否定查找 Negative lookbehind assertion: Matches “x” only if “x” is not preceded by “y”. For example, /(?<!-)\d+/ matches a number only if it is not preceded by a minus sign. /(?<!-)\d+/.exec(‘3’) matches “3”. /(?<!-)\d+/.exec(‘-3’) match is not found because the number is preceded by the minus sign.

__
话说这些翻译中文的确实有点难理解?

IgniteWhite
    7

IgniteWhite   8 小时 36 分钟前   ❤️ 5

实用角度出发:比如我问你,这个正则怎么写?你肯定知道我说的是正则表达式。
如果是规则表达式:这个规则怎么写?你会问我,什么规则?我说,匹配的那个规则。你问,各种 wildcard 和 globbing 都是匹配的规则,你说的哪个。我说,规则表达式那个。
vopin
    8

vopin   8 小时 21 分钟前 via iPhone   ❤️ 1

有可能是翻译的日语 正規表現
*近发现日语的数学、计算机词汇和中文很像
Leonard
    9

Leonard   8 小时 17 分钟前   ❤️ 12

专有名词翻译成一个非常用词,使用起来比较会没有歧义
anjianshi
    10

anjianshi   8 小时 16 分钟前

编程词汇翻译还扯什么文学素养,装逼…

FakNoCNName
    11

FakNoCNName   8 小时 11 分钟前

@anjianshi 难道你看现在这些年翻译的东西没觉得更难理解、更恶心吗。

现在的狗屁翻译,干脆都不翻译了,直接音译过来。

SilentDepth
    12

SilentDepth   8 小时 9 分钟前 via iPad

@anjianshi #10 不然。翻译就是翻译,跟主题无关。好的翻译对文学素养是有要求的。
kenvix
    13

kenvix   7 小时 59 分钟前

@anjianshi 不管什么领域,翻译都应该讲究信达雅
luckykong
    14

luckykong   7 小时 58 分钟前 via Android   ❤️ 1

@weixiangzhe 先行断言 和 Lookahead assertion,这两个哪一个都不好理解吧。好理解的是后面的英文解释说明。 但这样的话翻译成中文,也很容易理解啊
silkriver
    15

silkriver   7 小时 57 分钟前

追究一个词是古汉语词汇还是日语词汇是没有意义的,只要遵循汉语的基本法就是汉语。walkman 是日本人生造的,但它就是个英语单词。
huang119412
    16

huang119412   7 小时 56 分钟前

鲁棒性不服,感觉像拿着棒子打人?
koast
    17

koast   7 小时 53 分钟前 via Android

@weixiangzhe #6 确实,这些中文翻译我一开始看了就???看了英语原文之后也能理解为什么这么翻译,但是不得不说,这种翻译方法不是很直观(指看到词能猜到大概意思)
laoyur
    18

laoyur   7 小时 36 分钟前

@huang119412 看起来 说文学素养是装逼 的那人应该会喜欢 鲁棒性 这个翻译吧
Mohanson
    19

Mohanson   7 小时 21 分钟前

句柄…
plko345
    20

plko345   6 小时 59 分钟前 via Android

正则这个翻译很有水平啊
fredli
    21

fredli   6 小时 58 分钟前

有意思,这个翻译是大陆*先的么?还是香港台湾传过来的?
lujjjh
    22

lujjjh   6 小时 57 分钟前

很多词数学里也有,像函数( function )、正则( regular ),虽然 CS 领域的意思不太一样,但是翻译借鉴过来了。

不同地区的翻译也有区别,比如台湾就是把 regular expression 翻译成规则运算式。

southsala
    23

southsala   6 小时 50 分钟前

我刚学编程的时候,不明白健壮性是个什么鬼,编程和健身有什么关系。
aguesuka
    24

aguesuka   6 小时 48 分钟前

regularization = 正规化(数学)
normalizer = 中心化子和正规化子 (Centralizer and normalizer) 范畴学. 至少把这两个先区分再说有水平吧.
作为业余译者, 直觉上 “positivity” 才应该是 “正规”, 其它两个应该都应该换个翻译.
nullcoder
    25

nullcoder   6 小时 42 分钟前

@Leonard “专有名词翻译成一个非常用词,使用起来比较会没有歧义”

体会一下 memory 这个词在英语里的意思,觉不觉得这个词比起“内存”很形象?
而 k8s 里的 pod,至今没有统一 /官方的中文翻译。

aguesuka
    26

aguesuka   6 小时 30 分钟前

如果要重新翻译”正则”, 应该是意译, 需要蕴含 “字符串匹配表达式” 的含义, 或者像 “cron 表达式” 一样不要翻译. 直译”成规则”就是又重走把 “function” 翻译成 “函数” 的路, 也不好.
securityCoding
    27

securityCoding   6 小时 28 分钟前 via Android

@huang119412 这个鲁棒性真的是日了狗
mekingname
    28

mekingname   6 小时 27 分钟前

我理解的是:正则=> 如果[正]确[则]提取。
如果你的 pattern 写得正确,符合目标数据的格式,则把目标数据提取出来
aguesuka
    29

aguesuka   6 小时 8 分钟前

@jorneyr
https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE
和制汉语正規表現(せいきひょうげん、英: regular expression ).
和人文素养没有关系
aoeui
    30

aoeui   5 小时 51 分钟前 via Android

@huang119412
鲁棒性 台译:強健性
句柄 台译:把手
PrinceofInj
    31

PrinceofInj   5 小时 20 分钟前 via Android

这个翻译可以把鲁棒按在地上摩擦。
falcon05
    32

falcon05   5 小时 15 分钟前 via iPhone

规则表达式明显比较直观和准确,正则表达式?什么是正则,那反则表达式呢?
kinboy
    33

kinboy   5 小时 14 分钟前 via Android

@IgniteWhite wildcard 翻译为通配符,就是一个不错的示例,可以是一个专用汉语名词,也容易理解,基本上*次解除也能猜出个大概意思。
但是正则这个词在现代汉语中的使用频率应该非常低了,不去查一下还真不知道是什么意思
kinboy
    34

kinboy   5 小时 7 分钟前 via Android

@jorneyr 好的,谢谢
kinboy
    35

kinboy   5 小时 6 分钟前 via Android   ❤️ 1

@laoyur 哈哈哈说起鲁棒总是会想起鲁智深手持大棒 ?
jorneyr
    36

jorneyr   4 小时 51 分钟前

@aguesuka 可能你没注意,我提的是正则这个词的翻译比楼主提的规则从文学素养上来说更好,只是针对这个词,与其他方面无关。上面很多人也从各个方面进行了分析,大多人也认同正则比规则更合适。
libook
    37

libook   4 小时 8 分钟前

正则表达式的发明者是一个数学家,正则表达式是“形式语言学”的范畴,这一开始是属于数学领域的。

早先计算机还只是数学学科下的一个子学科,大量的概念都是来自于数学中的概念,比如咱们耳熟能详的函数;按照题主的思路,function 应该翻译成“功能”。

在数学中有很多跟 regualr 相关的概念,中文都是被翻译成正则,正则表达式可能是为了翻译上的统一性,所以也翻译成了正则。

至于数学上为什么这样翻译,有兴趣的人可以去考究一下,这个可能比较难,因为数学是一门古老的学科,有些数学概念甚至是古代的时候产生的,用的名字也是古汉语(比如勾股定理),以至于如今人们会觉得晦涩难懂。我个人更倾向的推测是,“正”是动词或副词性,“则”为名词性。

翻译成“规则表达式”确实浅显了,但不易懂,因为“规则”的含义太通用了,反而不能让人快速联想到是众多“规则”里的哪一种,而且并不是所有可以用来匹配字符串的“规则”都是 Regular Expression 。

即便是英语,同一个词汇在不同的语境下的意思也可能不一样,词典上的对照不是铁律,只是一种辅助意会的工具,否则机器翻译技术就不会那么难了。

falcon05
    38

falcon05   3 小时 43 分钟前 via iPhone

@libook 不要拿数学当挡箭牌好吗?数学还讲究对称呢?有正数有负数,有正则表达式,那负则表达式呢?
autoxbc
    39

autoxbc   3 小时 29 分钟前   ❤️ 1

译名一旦形成就没什么可争论了,举个例子:

近代翻译大家「严复」都知道吧,没人敢说比他更懂翻译,他非常执着的要把今天常用的「社会」(Society)一词翻译为「群」,你说严复对还是不对,这个事已经无法深究了。而「社会」其实是个日本造汉字词,这又涉及到现代汉语里大量的日本造汉字词,这又是另一个话题了

Kilerd
    40

Kilerd   3 小时 11 分钟前

技术圈的中文翻译你跟我说文学素养?
robust 鲁棒性
socket 套接字( socket programing 套接字编程)

还有吧 goroutine 翻译成 「 go 程」 的
你品,你细品

Biwood
    41

Biwood   3 小时 9 分钟前

*次听说“正则表达式”这个词语,感觉挺唬人的,直到后来真正学习了并且用起来之后才发现,也就那样…

查了一下
台湾翻译:正规表达式
日本翻译:正规表现

对比一下,会发现“正则”的歧义更少。这大概是语言的接受程度跟语言本身的独特性中间的一种取舍。

generic
    42

generic   2 小时 15 分钟前

@Leonard 那你把数学里 群,环,格,特征,理想 等等常用到不能再常用的词,给换个“比较会没有歧义”的版本呗
Leonard
    43

Leonard   2 小时 0 分钟前

@generic #42 我换了又不算
adoal
    44

adoal   1 小时 27 分钟前

可能*个这么翻译的人是刘仁轨的粉丝。

千万不要升级 Firefox 91 版

千万不要手贱升级 Firefox 91 版, Proton 禁用也无法换回原来的 Tab 栏了

 7 小时 40 分钟前 · 1944 次点击

Proton 目前个人感觉很耗资源,禁用后速度有明显提升,而且 Proton 的 Tab 占据太多空间,以前很多基于 Firefox 的 UI 测试直接无法运行。

Firefox 91 之前的版本,包括默认启用 Proton 的 Firefox 90 版本,都可以在 about:config 里面 disable 掉 Proton,从而恢复成原来紧凑的模式,如下图所示: %title插图%num

更新到 91 版之后,即使是 disable 掉了 Proton,紧凑的 Tab 栏也回不去了,如下图所示: %title插图%num

目前在网上找了一圈,github 上有个 Firefox UI 用自定义的方式实现了类似的风格,但是是在启用 Proton 的条件下(原文没仔细看,好象是利用 Proton 能自定义界面的特性实现的),跟以前紧凑的风格明显不一样,而且能感觉明显卡顿。网址: https://github.com/black7375/Firefox-UI-Fix 显示风格如下:

%title插图%num

27 条回复    2021-08-16 16:23:54 +08:00

chutsetien
    1

chutsetien   7 小时 33 分钟前   ❤️ 1

不是 > Proton 禁用也无法换回原来的 Tab 栏了 <,而是,Proton 已经不可禁用了。

Aris-t2 的 Custom CSS for Firefox ( https://github.com/Aris-t2/CustomCSSforFx) 试过了吗?

要认真读 userchrome.css 里的每一个选项哦。

比较奇怪的是,我自从 Firefox 29 开始就坚持要还原 Firefox 4 – 28 的外观,57 时也是(从那时起就使用 Custom CSS for Firefox 这个项目),甚至在 91 的 beta 阶段还是(认真改还是能大概改回 Firefox 4 的样子的,就是对话窗口不再是系统原生的了)。但突然间就向 Proton 和解了。觉得 Proton 也挺好看的,现在唯有的修改就是汉堡菜单在左上角、Megabar 联想项的标题和地址分两行显示。

snuglove
    2

snuglove   7 小时 28 分钟前

我用 vivaldi…
shijingshijing
    3

shijingshijing   7 小时 18 分钟前

@chutsetien 我在 91 版的 about:config 里面还是能够禁用掉 Proton 的,界面和启用 Proton 时有明显区别,那个右键菜单就能看出来,禁用之后是没有前面的小图标的。所以应该是能禁用,但是 Tab 确实是回不去了。

性能方面也有明显区别,冷启动时,能够明显看到 Bookmark 从左到右刷新的过程,而不是以前那种秒开。右上角的面包菜单点击之后,也能明显看到图标刷新的过程。

不明白现在这些公司一天到晚折腾 UI 干什么,有这功夫用来提升性能多好啊。。。

ScotGu
    4

ScotGu   7 小时 18 分钟前   ❤️ 1

浏览器厂商为啥都喜欢这么改变用户使用习惯呢。
chutsetien
    5

chutsetien   7 小时 14 分钟前

@shijingshijing 我知道啊,Proton 就是从 91 开始不被允许禁掉的。这个在 89 的时候大家就知道了。

我以前一直要把 Fx 维持在这样的样子才舒心
%title插图%num

但现在突然觉得这样也不错
%title插图%num

重点在右键菜单上下功夫:
%title插图%num

%title插图%num

%title插图%num

%title插图%num

再把汉堡菜单移到左上角
%title插图%num

我觉得就够了。

wudicgi
    6

wudicgi   7 小时 1 分钟前

我到现在都在怀念 Tab Mix Plus 扩展

从 Firefox 57 开始,它的 tab 管理就和 Chrome 等浏览器一样弱鸡了,只能开一行, tab 一多就没法用了
以前有 Tab Mix Plus 扩展时,经常一个 window 开到两三百个 tab

raycool
    7

raycool   6 小时 38 分钟前

确实 升级后发现了

好坑啊
不给用户选择

reiji
    8

reiji   6 小时 36 分钟前 via Android

软件的设计不可能什么设计和功能都留一个切换的选项的,只能说多习惯下说不定就顺眼了呢
vishun
    9

vishun   6 小时 24 分钟前

@wudicgi
火狐的 tab 原先有官方的 tab groups,非常好用,后来停止支持了,不过还有 Panorama Tab Groups 这个替代品还不错,,感觉是唯一比 chrome 好的地方了。
dfkjgklfdjg
    10

dfkjgklfdjg   6 小时 8 分钟前

有一个疑问哈,不是质疑你们喜欢客制化的好兄弟,就是真的 UI 改动,比如说 Tabs 的样式和书签栏的样式,
影响很大吗,是 会 [影响到你日常的使用] 还是 [单纯的只是不喜欢 /不习惯] ?
第二个,我看有很多 V2er 客制化了很多自定义功能,这类的变更会有影响吗?我一直都是用的默认….之前看 V2er 分享得 [Firefox 染山霞] 就觉得挺好看,但是我比较害怕自定义或者使用主题会影响浏览器的启动速度,看了两眼就会回到默认主题了,插件也是尽量只保持了一些开发者工具和方便调试的。
![桌面]( %title插图%num)

 

wudicgi
    11

wudicgi   6 小时 3 分钟前

@vishun 谢谢,试了一下,感觉用这个扩展和开多个 window 差不多,和 Tab Mix Plus 的多行 tab 不一样

我开两三百个 tab 时,就是简单地让他们多行依次排列,比如每行有 30 个 tab header, 一共 10 行 (只显示 3 行,可上下滚动) 就能容纳下 300 个 tab

shijingshijing
    12

shijingshijing   5 小时 59 分钟前   ❤️ 1

@dfkjgklfdjg 随便改动界面和显示风格对基于 UI 的测试影响*大,*严重的情况下需要对所有测试用例进行更新才能继续使用。Chrome 就是因为自动更新且很难禁止被我们抛弃了,Firefox 是可以禁止自动更新的,但是会提示你。

其实我个人感觉软件*重要的是安全和稳定性,UI 一旦成熟*好就不要动了,除非是出现了手机触控这种划时代的变革,否则所谓的提升生产力扯淡的成分居多,更大意义在于帮负责 UI 的刷 KPI 。

wudicgi
    13

wudicgi   5 小时 56 分钟前

手头没有实际使用壮观场景的截图,截了一个开一堆 new tab 时, Firefox 52 + Tab Mix Plus 的标签栏效果

%title插图%num

新的 Firefox 我也试过靠修改 userChrome.css 实现多行 tab, 看着差不多,但实际用起来很多行为是有 bug 的

francis59
    14

francis59   5 小时 56 分钟前   ❤️ 1

可以通过这个设置恢复紧凑模式:about:config -> browser.compactmode.show=true

具体操作: https://support.mozilla.org/en-US/kb/compact-mode-workaround-firefox

shilianmlxg
    15

shilianmlxg   4 小时 23 分钟前

问下 大佬 ,类似的 chrome 设置允许跨域操作 firefox 怎么设置呢
windows
–args –disable-web-security –user-data-dir=”C:/ChromeDevSession”
mac
open -a ‘Google Chrome’ –args –disable-web-security –user-data-dir=/tmp/chrome_dev_test
autoxbc
    16

autoxbc   4 小时 14 分钟前

*终你会适应这个,C’est La Vie
shijingshijing
    17

shijingshijing   3 小时 32 分钟前

@francis59 实测 Firefox 91 版本不行,估计是以前的版本可以这样弄。
francis59
    18

francis59   3 小时 16 分钟前

@shijingshijing 我用的就是 91 啊,你确定按上面的链接操作了?

%title插图%num

francis59
    19

francis59   3 小时 14 分钟前

%title插图%num
raycool
    20

raycool   3 小时 5 分钟前

@francis59 我记得以前的版本是设置两个地方,一个是使用紧凑模式,一个是禁用掉 proton,这样标题栏就和以前的主题一样,现在禁用 proton 不管用了~
francis59
    21

francis59   3 小时 2 分钟前

@raycool 不需要禁用 proton,只需要选择使用紧凑模式就可以了,91 版本实测
foMM
    22

foMM   3 小时 0 分钟前

难道只有我喜欢新的标签栏吗……我也是因为这个原因重新使用 firefox
dfkjgklfdjg
    23

dfkjgklfdjg   2 小时 49 分钟前

@shijingshijing #12,呃,我说的是对于我们这类的浏览器用户来说是否有破坏性,比如说影响使用之类的,不是说自家产品的 UI 改版对于项目的影响….
shijingshijing
    24

shijingshijing   2 小时 32 分钟前

@francis59 我试了啊,Tab 跟地址栏之间还是一条缝隙,只不过 Tab 变小了,我想要的是原帖里面*张图的样子,这个 Compact 只是把第二张图的 Tab 弄得小一号,变窄了而已。。。
francis59
    25

francis59   2 小时 18 分钟前

@shijingshijing 你说的是 tab 和工具栏连在一起的样式吧,那就得自定义 userChrome.css 了

可以看一下这个: https://www.userchrome.org/firefox-89-styling-proton-ui.html
里面的”Tabs floating or connected: ” 是设置这个的

%title插图%num

jasonyang9
    26

jasonyang9   2 小时 9 分钟前

个人对这类 UI 变化不敏感,无所谓,或者说适应性比较强
jinqzzz
    27

jinqzzz   1 小时 19 分钟前

习惯开一对标签页,然后用 sidebar 插件

SpringSecurity 我怕了

*近项目用了 security 需要对接钉钉和企业微信的登录,看了下官方文档,在 5.2 之前需要引入一个 oauth 包,后面 5.2 需要引 ouah2-client 包,开开心心的引入了,才知道噩梦才开始
官方自带的配置文件使用 client_id 字段作为默认 appKey,但钉钉叫 appid 、、、需要单独配置一个 resolver 去替换
换好了,发起授权正常,轮到回调 code 了,默认的直接是直接把 code 码 post 到指定的网址,结果钉钉也不一样,需要签名,然后又配置一个 converter,
我现在犹如吃了屎一样难受,我直接自己写个应该已经好了也不至于浪费一天时间

总结一句话,如果要对接 oauth2,请直接避开官方提供的代码,直接手撸

config

16 条回复    2021-08-16 17:16:08 +08:00

ifsclimbing
    1

ifsclimbing   2 小时 1 分钟前

人生苦短, 我用 python
Sasasu
    2

Sasasu   1 小时 59 分钟前

「面向切面编程」
Grande
    3

Grande   1 小时 55 分钟前   ❤️ 1

这味道比杯子里面的拿铁还新鲜
HiShan
    4

HiShan   1 小时 52 分钟前

这只是 Security 的一个认证功能吧。它还提供后续很多其他权限管理的功能不需要自己实现
qwerthhusn
    5

qwerthhusn   1 小时 52 分钟前

从来不用 Spring Security,只是感觉这玩意增加工作量的

自己手写也不算很复杂

jorneyr
    6

jorneyr   1 小时 50 分钟前

为了支持更多的第三方 OAuth2,直接用 JustAuth,ScribeJava 等 OAuth2 工具直接硬上,实现一个 OncePerRequestFilter 到 UsernamePasswordAuthenticationFilter 前面是不是更直观。
HiShan
    7

HiShan   1 小时 50 分钟前

@HiShan 如果只需要 OAuth2,完全可以自己实现。
totoro52
    8

totoro52   1 小时 49 分钟前

@HiShan 是的 security 提供的一个用于 oauth2 认证的包,我起初天真的以为 这玩意拿来就能用,但是发现,钉钉的流程完全就是魔改了,如果要对接 github google,YouTube 等网站,可以用这个包,因为官方默认就提供了支持,配置几行就能用,国内的应用请直接避开,配置到*后你会发现根本用不了
totoro52
    9

totoro52   1 小时 48 分钟前   ❤️ 2

虽然吃了点亏 但还是把 oauth2 源码看了个遍 还是学了点东西
ikas
    10

ikas   1 小时 40 分钟前

如果你又需要对接另一个接口.他又有不一样的配置,是不是自己又要 copy 代码写一套?

totoro52
    11

totoro52   1 小时 39 分钟前

@ikas 是的 比如我要对接企业微信 企业微信的流程比较规范 所以不需要改动很多 ,但钉钉我是真怕了

warcraft1236
    12

warcraft1236   1 小时 37 分钟前

这只能说明钉钉垃圾啊,手动狗头
totoro52
    13

totoro52   1 小时 35 分钟前

@warcraft1236 钉钉的这个流程我是没想到 大意了 更骚的还是钉钉提供了 sdk 但没有上 maven 我只能自己传到私有库
shot
    14

shot   53 分钟前

钉钉的锅,不要甩到 Spring Security 上。
XhstormR02
    15

XhstormR02   17 分钟前 via Android

Spring Security 还是很好用的
a728976009
    16

a728976009   2 分钟前

oauth2 协议里就是 clientid,这只能说明叮叮没支持标准的 oauth2 或 oidc 协议

MIUI *近那个原子内存是什么原理?

MIUI *近那个原子内存是什么原理?

 

ysy950803 · 1 天前 via Android · 7721 次点击

*近雷布斯的演讲有点意思,不过我更好奇那个 12.5 增强版(其实就是超级 Bug 修复版)里提到的原子内存,我看介绍大概是可以回收各个应用进程内部的局部内存,这样可以使得可用内存更多,后台被杀的概率降低。

但是这个回收局部内存是咋做到的?比我我在微信聊天,但是支付暂时用不到,可以回收,系统如何判定的?

84 条回复    2021-08-13 14:31:22 +08:00

ysy950803
    1

ysy950803   1 天前 via Android

“比我”->“比如”
AoEiuV020
    2

AoEiuV020   1 天前

这,gc ?总不可能回收有强引用的内存,那就是杀后台了,
而且我是不信 miui 内存多了就不杀后台的,我 8G 内存时常剩 4g,照样死命杀后台,
heiher
    3

heiher   1 天前 via Android   ❤️ 2

或许就是 swap 吧 😀
Mcx
    4

Mcx   1 天前

感觉是忽悠人的
tyzrj766
    5

tyzrj766   1 天前   ❤️ 1

看酷安上面说就是把一个 APP 的服务分开去杀进程,例如一个微博有多项服务,需要内存资源的时候先杀个广告服务,不够了再杀另一个,不会干掉主程序。类似之前写轮眼吧,折腾安卓的应该都用过,以前我就是把百度输入法的服务留了一两个主要的,其他没用的全关了。
yanzhiling2001
    6

yanzhiling2001   1 天前

swap
tyzrj766
    7

tyzrj766   1 天前

@tyzrj766 #5 应该不是虚拟内存那么简单的东西,倒是*近看蓝厂还是绿厂有类似的操作,把 ROM 空余的一小部分增加一小部分虚拟内存用,反正现在动不动 128G 256G 的,拿个 2G 、4G 也无所谓。
kokutou
    8

kokutou   1 天前

swap 吧..
开发版已经实装了…叫内存扩展
hello2066
    9

hello2066   1 天前   ❤️ 2

他就是原子嘛,利用原子的运动型,多样性,轨迹性。很多原子分配给各个进程,更好的监控进程嘛,预计你要开哪个,要关哪个。机器学习嘛,顶级操作系统功能,预加载,分片性,原子之间互相联系互相通讯,系统结构更紧凑响应更快。
murmur
    10

murmur   1 天前

定向杀进程吧,反正国内常用的 app 一把手就数的过来,能解决阿里腾讯头条就可以拿出来吹了

yinusxxxx
    11

yinusxxxx   1 天前

应该还是虚拟内存,把应用从 RAM 换出到 ROM 上,再加上 POSIX 提供了可以把一部分内存 pin 住不换出的系统调用,可以更加精确控制吧

Dona1d
    12

Dona1d   1 天前

@kokutou 把整个内存比作房子,进程是住客。内存扩展是增加房间,我 12G 的感觉没什么用。原子内存应该是类似在保留*基本的住的需求的情况下。如果人少,住客就能享受完整的套房,如果人多,有的住客就会分到客厅、书房、厨房来住。
yukiww233
    13

yukiww233   1 天前   ❤️ 1

看起来搜集一些主流应用的 activity 按优先级挑着杀, 而不是整个进程杀掉
但问题是, ram 占用大头不是这个啊…
感觉还是营销概念大于实际作用
pengtdyd
    14

pengtdyd   23 小时 49 分钟前   ❤️ 39

国内企业总喜欢搞这种微创新,然后起个看起来很厉害的名字,你说他有用吧,确实有用,你说他没用吧,也确实没啥用,都是鸡肋罢了.说白了还是格局被局限了,android 系统就像围城,很多企业在里面绞尽脑汁的”创新”.如果以后出现一个颠覆性的产品出现,直接改变行业规则,就像马斯克之于汽车行业一样,那么这些企业就会像跟屁虫一样,去追随下一个颠覆者.
hhjswf
    15

hhjswf   22 小时 39 分钟前

听金凡吹,我感觉 jvm 应该请他过来指导,java 就稳坐*了?
Maboroshii
    16

Maboroshii   22 小时 37 分钟前

我倒是觉得哪个存储空间碎片整理的不错,不知道原生安卓有没有第三方应用能实现这个优化的
zcfnc
    17

zcfnc   22 小时 36 分钟前

# 14 不能再同意十四楼的说法,国内的很多东西光看名字和描述都以为我们*别人几十年技术了,然后扒了皮一言难尽
xishijt
    18

xishijt   22 小时 25 分钟前

先把明明内存还剩一半,但是拼命杀后台的机制解决再说其他的
littlewing
    19

littlewing   22 小时 23 分钟前

ppt
juded
    20

juded   22 小时 20 分钟前

这个问题要问市场营销部门
qsmd42
    21

qsmd42   22 小时 7 分钟前

@hello2066 明天来华为入职!
qsmd42
    22

qsmd42   22 小时 5 分钟前   ❤️ 2

@Maboroshii 这个碎片整理我就更不明白了 闪存不是不需要碎片整理吗
jingslunt
    23

jingslunt   22 小时 0 分钟前

@hello2066 明年应该会出量子 cpu,齐点设备,抗熵增存储 怕不怕
vmebeh
    24

vmebeh   21 小时 50 分钟前 via iPhone   ❤️ 4

要不是国内软件各种骚操作、流氓一样保后台,也不需要这类东西
andyskaura
    25

andyskaura   21 小时 48 分钟前   ❤️ 1

@xishijt 拼命杀 拼命开 一边杀 一边开 只能说 生态太差了
blessingsi
    26

blessingsi   20 小时 6 分钟前

什么时候这种东西不是放在发布会上发布,而是放到开发者大会 or 发 paper 出来,让大家看看到底是个什么东西。
mu2er
    27

mu2er   17 小时 19 分钟前 via iPhone

这东西概念吹得可真厉害,像当年小米 5 发布时吹得各种黑科技,到手发现就那个样世界烂大街的功能。
chenyx9
    28

chenyx9   16 小时 58 分钟前 via Android

@jingslunt 这么大计算力的配置,耗电也挺吓人吧。建议先出氚聚变电池。
iOCZ
    29

iOCZ   16 小时 54 分钟前

感觉粒度到你说的支付功能不现实。首先你写程序你应该知道,你没用到的功能,是不太会占用内存的,其次用完了也会释放。因此减少驻留内存才是关键吧。
tanranran
    30

tanranran   16 小时 18 分钟前

楼上各种喷的人用一下就知道了,感知还是很强的
tanranran
    31

tanranran   16 小时 16 分钟前   ❤️ 6

原理是:正常情况下的安卓内存管理机制,是以 APP 的个数为基本单位的。比如你打开了微信,哪怕只是聊天,也要承担微信里比如定位、小程序、游戏。支付等功能同时唤醒带来的内存占用。要么都去掉,要么都接着。MIUI 新的 RAM 管理机制呢,则是将管理基本单位进一步细分、精确到了“项”,你打开微信,只聊天,那就只保留聊天,其他没用的功能,都给我乖乖地冷藏着。
Maskeney
    32

Maskeney   16 小时 5 分钟前

ZRAM 拉大点?
tanranran
    33

tanranran   16 小时 4 分钟前

@iOCZ 大哥,一看你就是没写过安卓,安卓中的多进程和多服务还是很好资源的
jim9606
    34

jim9606   15 小时 41 分钟前

主要问题是,当今能够大幅提升性能的改进,是少不了端对端的配合的,现在已经没有改改硬件或者系统、无需 APP 修改就能获得 buff 的事了。

而且我是很奇怪怎么这个 MIUI 连版本号都不刷了,叫个 12.6 都好些,12.5 名声已经不好了,在 marketing 角度来看,就算新版本改好了,公众也很难摆脱以前的负面印象。

@pengtdyd 革命性变化这种东西少也要 5-10 年的周期,而且初期肯定伴随着一大堆槽点的,指望一个成熟技术的常规迭代整这个就是不现实的。另外也别说只是国内公司这么干,国外公司也一样,PPT 看着牛逼的东西,要么有严苛的限定条件,要么未来可期那种。

ajaxfunction
    35

ajaxfunction   15 小时 25 分钟前   ❤️ 1

吹牛皮的东西,
代码里少个换行符,
到他嘴里都能变成,代码体积减少 3%,编译速度提示 2%,运行史诗般流畅。
muzuiget
    36

muzuiget   15 小时 16 分钟前

@ajaxfunction 你泄漏天机了。
wikiwiki6
    37

wikiwiki6   14 小时 50 分钟前

swap 而已
不懂技术的又被忽悠
Huelse
    38

Huelse   13 小时 49 分钟前

真的只是 swap 吗?我记得安卓的内存机制和 linux 不一样
WebKit
    39

WebKit   13 小时 29 分钟前 via Android   ❤️ 15

不是 swap 。很多人 android 开发一点不懂,甚至连*近几代的 android 手机都没用过就开始云了。
玩儿过 android,刷过机的基本都知道写轮眼吧。这就是官方写轮眼。实在不知道你看看正在运行的进城服务跟以前有什么不同不就知道了吗
LeeReamond
    40

LeeReamond   11 小时 9 分钟前   ❤️ 9

本帖是观察米黑反科学程度的良好素材,很多人是跟事实无关的直接云,然后估摸了一个自己理解范围内的东西,然后直接开喷
fateofheart
    41

fateofheart   10 小时 56 分钟前   ❤️ 2

真的是,很多人对安卓根本就不了解,看到内存两个字就知道 swap 。。。
不过,这个“原子”内存活该被喷。。。
murmur
    42

murmur   7 小时 3 分钟前   ❤️ 5

@pengtdyd

什么叫不微创新

坚持 5v1a 不动摇?
夹层主板?
没有通话录音?
没有工作日闹钟?
NFC 不能复制卡片?

pengtdyd
    43

pengtdyd   6 小时 51 分钟前

42 楼 在监狱的小吴总是有一些狂热的追随分子,这些人常人很难理解,但是他们就是存在,很恶心人
murmur
    44

murmur   6 小时 41 分钟前   ❤️ 12

@pengtdyd 有本事这辈子苹果不要用屏下指纹、屏下相机、真全面屏,到时候我天天在 v2 看你的回复,看你是怎么看待苹果追随安卓微创新的

有些人就是跪洋人跪傻了,我话就扔着了,没小米就没安卓手机的今天,硬件不如人,软件不如人,体验再不针对优化,直接输麻了

苹果粉丝天天吹什么动画、吹那几个圆角、微创新,这是不是微精细度啊?好家伙,没有这么双标的,苹果叫工匠精神,到安卓就是无关紧要的微创新

苹果酒喜欢这种花了钱还帮着洗地的,以后中国人需要的功能统统排*后,还有大笔的苹果税奉上

x500
    45

x500   6 小时 40 分钟前

利用 hook+打桩 stub 就可以实现吧, 好久以前 miui 不是里面”借鉴”了 xp 的代码吗?
coolair
    46

coolair   6 小时 31 分钟前

跟魅族的 OneMind 样,说起来高大上,用起来坑死人的东西吧。
SenLief
    47

SenLief   6 小时 29 分钟前 via Android

应该就是 swap,oppo 还是 vivo 来着不就有,写着可以把内存 8g 扩展到 12g 。不过我还是希望有华为功能那个 app 后台常驻,不知道怎么实现的,比如知乎在某个页面切换其他 app,知乎不会重启了,好几天还在那个页面。
Building
    48

Building   6 小时 23 分钟前 via iPhone

头疼医头,脚疼医脚的典型,你说内存不够,8G12G 还不够?你说 App 流氓,你个系统连 App 都管不好?
elfive
    49

elfive   6 小时 22 分钟前 via iPhone

应该改名叫上夸克内存或者奇异夸克内存,毕竟大部分人还是知道原子并不是*小粒度
pengtdyd
    50

pengtdyd   6 小时 21 分钟前

以后多去牢里面看看小吴,聊聊一块钢板的广告之旅
nexmoe
    51

nexmoe   6 小时 20 分钟前

应该就是每个应用的不同功能有各自的进程吧,比如下图的鸿蒙 OS 中的详细信息就有不同的进程,杀掉暂时不用的进程就行了
![图片来自酷安]( https://files.catbox.moe/sw8unq.jpg)
butanediol2d
    52

butanediol2d   6 小时 13 分钟前 via iPhone

@qsmd42 可能是类似 trim 、防止写入放大之类的操作吧,叫碎片整理为了方便营销?
sexoutsex2011
    53

sexoutsex2011   6 小时 10 分钟前

实际效果应该会弱于宣传效果
Eagleyes
    54

Eagleyes   6 小时 4 分钟前

@pengtdyd #14 你说的这种事情适合于各种行业。我觉得主要问题没本事,其次是输不起。

1 、没本事,小米也要自己研发一个 HM OS ?估计没这个实力(何况这个系统也被人说套壳),另外也没人用自然就被时间淘汰了。国外强如微软 WP,2013 年听的是,三分天下,后面直接取消变成 iOS 和安卓二分天下,你凭啥认为自己有这个实力和号召力?

2 、没钱,小公司就不说了,哪怕强如 BAT,其中有像 Google X 这么个烧钱部门么?舍不得烧钱,输不起。

3 、聪明(鸡贼),做*个吃螃蟹的人自然发财,但是*大多数会变炮灰。等你研发出一个被市场证明,我在跟着学(致敬),岂不是稳扎稳打没风险?这就是你说的 Tesla 。。

非不为也,实不能也

anguiao
    55

anguiao   5 小时 58 分钟前

@pengtdyd 属于是不带“国内”两个字不会说话了。
Android 原生的很多机制并不能适应国内的应用生态,国内厂商做一些优化再正常不过了。
每家都开发一个自己的系统是不现实的,能引领潮流的企业也永远都是少数。
miaoda
    56

miaoda   5 小时 54 分钟前

![miui12.5 内存扩展]( https://cdn.jsdelivr.net/gh/WitMiao/blogPic/img/miui12.5%E5%86%85%E5%AD%98%E6%89%A9%E5%B1%95.jpg)
a22271001
    57

a22271001   5 小时 37 分钟前   ❤️ 1

内存扩展和原子内存是两个不同的东西啊喂,先区分好两个东西再发言好吧
villivateur
    58

villivateur   5 小时 35 分钟前 via Android

楼上某些人是不看题目,见到“内存”两个字就扯 swap ?杀进程跟 swap 有啥关系?
pengtdyd
    59

pengtdyd   5 小时 10 分钟前

确实优化优化 android 是属于正常不过的行为了.优化优化系统壁纸,改改字体,替换一下 GMS 框架,加些系统广告,再用一下奥氏体 304,艺术化一下,简直完美.
sockpuppet9527
    60

sockpuppet9527   4 小时 50 分钟前

歪个楼,提到“原子”,有没有可能是把 mmu 改了一下,留了一些 unmap 的内存? 不走 mmu 的内存连续且好置换,也好回收?
ZoteTheMighty
    61

ZoteTheMighty   4 小时 50 分钟前   ❤️ 10

作为一个 android 开发表示,真的有些人在自己不懂的领域张口就来,android 一个应用程序可以有多个进程,进程又分为 5 个级别,像很多通知栏的常驻通知就是一个 Foreground 进程,优先级*高,所以很多软件要求常驻通知栏来实现保活,大部分毒瘤 app 都会有多个进程,MIUI 应该就是精细管理这些进程,优先保持前台进程不被杀死。 有些人听到 swap 这个关键词就原地高潮,哦,他懂了,可是又不完全懂,可是他还想发表下高论,这样。
zpxshl
    62

zpxshl   4 小时 35 分钟前 via Android

@ZoteTheMighty 61 扯啥呢,前台进程本来就比后台进程高优,这还需要 miui 优化?
murmur
    63

murmur   4 小时 31 分钟前

@zpxshl 不一定哦,现在一些游戏允许后台下载的,这个时候你要杀前台保后台
ZoteTheMighty
    64

ZoteTheMighty   4 小时 23 分钟前

@zpxshl 建议仔细看下, 关于怎么杀进程,杀哪个操作系统会有一套逻辑判断,MIUI 魔改这一部分一点都不奇怪,各家都有魔改过。
Unclev21x
    65

Unclev21x   3 小时 59 分钟前

盖楼 60 多层。如果,我是说如果答案真如 @ZoteTheMighty 所说,那我觉得这个原子内存还是不错的,很实用。

V2 现在不管什么问题,都流行冷嘲热讽互相喷吗?骂完苹果骂华为,骂完华为骂小米。骂完小米骂苹果。

夸一个要拉另一个垫背,围魏救赵。

看的真是累啊。

Threeinchtime
    66

Threeinchtime   3 小时 38 分钟前

感觉说 swap 的根本没看这个功能描述
MrKrabs
    67

MrKrabs   3 小时 33 分钟前

就改个杀进程那不是更 low 了(
generic
    68

generic   3 小时 32 分钟前

@tyzrj766 zram? android4 就可以开…
ApmI00
    69

ApmI00   3 小时 23 分钟前

扯这么多,买个来用用不就知道啦!!!非要像一群博士吵吵万米高空一滴水的动势能。。。
tanranran
    70

tanranran   2 小时 54 分钟前

楼上至少有 80%的人在那瞎扯,回复的内容和问题毫不相关,上来就是喷。
kindjeff
    71

kindjeff   2 小时 53 分钟前 via Android

我就想问问 miui 为啥不写文档?学习鸿蒙么
liyhu
    72

liyhu   2 小时 12 分钟前

在营销厂找技术?
cairnechen
    73

cairnechen   2 小时 2 分钟前   ❤️ 1

说实话,很难发现一个比 @murmur 更令人讨厌的人,所以我一般都是站在他的对立面,不过 @pengtdyd 你做到了,赏你一个 block 名额
pengtdyd
    74

pengtdyd   1 小时 58 分钟前

@cairnechen 啥是 block 名额?
bigbigpeng3
    75

bigbigpeng3   1 小时 24 分钟前

@pengtdyd 你被他屏蔽 /拉黑了。
Lemeng
    76

Lemeng   1 小时 23 分钟前

看很多人说是 swap,如果真是,那还挺有意思的
newmlp
    77

newmlp   1 小时 2 分钟前

这不就是 swap 吗,把不活跃内存交换到磁盘上
newmlp
    78

newmlp   1 小时 0 分钟前

@tyzrj766 虚拟内存还简单?
WebKit
    79

WebKit   55 分钟前 via Android

@newmlp 并不是 swap
Bigglesworth
    80

Bigglesworth   45 分钟前

@pengtdyd #47 还有个大吴,秀波
wooody
    81

wooody   38 分钟前

大家都知道雷布斯喜欢把一些东西说的有逼格一点来吸引人,说这个功能对消费者而言是鸡肋的人的心态我是实在没想通。
一个纯技术讨论帖,知道的就发表一下意见,不知道的就听听人家的高见,或者提供下思路。
看了某人的历史发帖,不少自以为是的抖机灵,实际上对人家楼主 p 用没有,说真的我真想让 v 站发一个回复减 100 铜币。
zhouxuchen
    82

zhouxuchen   36 分钟前

@wooody #81 被你一说我好奇点了这人主页,好家伙比太平洋都水
newmlp
    83

newmlp   25 分钟前

@WebKit swap plus ,super swap,swap pro plus,原子内存。。。。。无非起个不一样的高大上的名字而已
chenrui920614
    84

chenrui920614   18 分钟前

有些人看个名字就高潮了

Android 特定用户使用时系统关机

特定用户使用时系统关机

 

wikiwiki6 · 2 小时 45 分钟前 · 472 次点击

定制设备,用户反馈用时自动关机 机器拿回,无论如何无法复现问题,换了好几台新机器还不行(电源键真的没有卡住,电池有电 让用户找了朋友测试,不关机(用户离机器 10 米距离 真的会有这种灵异事件吗? 大佬们怎么解,怎么排查

17 条回复    2021-08-13 14:37:41 +08:00

wikiwiki6
    1

wikiwiki6   2 小时 44 分钟前

难道只能请走近科学了吗
systemcall
    2

systemcall   2 小时 38 分钟前

如果是插电的东西,感觉可能是客户那边的电压的问题
还有可能是温度、湿度
tiancaixiaoshuai
    3

tiancaixiaoshuai   2 小时 24 分钟前

我遇到过相似的问题,你可以参考一下

几年前买了 vivo x510t,手机玩一段时间,再打开*品飞车的时候就会自动关机,有关机画面的那种,重新开机,再打开*品飞车,随便怎么玩,都没事

要说是内存不够,重新开机后打开多个软件,再打开*品飞车也没事,只要是重启过就一切正常,但是用一段时间,就会出问题

你可先用有问题的机器正常使用一天,再打开软件试试

wikiwiki6
    4

wikiwiki6   2 小时 4 分钟前

@systemcall 同样的环境,换个人就可以,太离谱了
wikiwiki6
    5

wikiwiki6   1 小时 57 分钟前

客户那边很生气,说我们推卸责任,但这太离谱了
est
    6

est   1 小时 10 分钟前

电磁脉冲
826540272
    7

826540272   1 小时 9 分钟前

走近科学 请
Hstar
    8

Hstar   1 小时 1 分钟前

派个人跟着客户,看他怎么用的
yfugibr
    9

yfugibr   1 小时 0 分钟前 via Android

和网络连接有关系没
goodryb
    10

goodryb   1 小时 0 分钟前

@wikiwiki6 #5 肯定是有什么因素没抓到,让客户现场重现故障

wikiwiki6
    11

wikiwiki6   29 分钟前

@goodryb 用户拍了视频,甚至手都没碰,还是有问题

wikiwiki6
    12

wikiwiki6   29 分钟前

@est 现实中有这种故障吗?
wikiwiki6
    13

wikiwiki6   28 分钟前

@yfugibr 这种问题应该跟网络没啥关系
yuancoder
    14

yuancoder   18 分钟前

这个就是用户的问题吧
since1997
    15

since1997   14 分钟前

给客户换台新的
no1xsyzy
    16

no1xsyzy   10 分钟前

奉上经典:控制变量法
你需要人员去现场严格控制变量。

其次是关机的情况是否可以暗示导致关机的物理界面,比如是电源按钮被触发,可以带示波器测量电源按钮的芯片引脚。**端的情况下,有可能是现场或者用户携带物产生的某个电磁信号被芯片误认为电源按钮被按下。

est
    17

est   7 分钟前

@wikiwiki6 有。网线、USB3 之间会相互干扰。2.4G 蓝牙之类的干扰也很多。但是对电源的干扰没具体摸过。