android - 如何在 SQLite 中显示从数据库到活动的查询?
问题描述
我正在开发一个包含计时器并将时间保存到 SQLite 数据库中的应用程序,我想使用保存的这些时间来获得另一个活动中文本视图的平均时间结果,有什么办法吗?我一般是编程新手,但我还没有找到方法来做到这一点。对于我所看到的查询 SELECT AVG(time) FROM TIMETABLE 在数据库检查器上运行良好,我只需要在文本视图中获得该结果。
解决方案
我想使用保存的这些时间来获得另一个活动中文本视图的平均时间结果,有没有办法做到这一点?
是的,毫无疑问。尽管您的意思是实际保存在数据库中还是仅仅意味着提取会使过程有所不同。可能只是后者,因为可能不需要永久保存结果(见下一部分)。
在另一个活动中获得文本视图的平均时间结果。
这可以直接从活动中提取/由活动提取,似乎几乎不需要保存通行证并提取父活动中的平均值。但是同样,如果您的意思是来自一组而不是整个数据(SELECT AVG(time) FROM TIMETABLE
作为整个数据)WHERE
的平均值,而如果应用了一个子句,那么一组将是,那么WHERE
可能需要从父级传递驱动程序/参数活动到子活动,这可以通过在开始子活动之前添加 Intent 额外内容然后在子活动中提取它们来完成。)
无论哪种情况,您都可以:-
- 实例化 Database Helper 的实例(使用子活动中的 Context 的 SQLiteOpenHelper 的子类)
- 使用
rawQuery
或最好使用该query
方法返回适当的Cursor
使用/构建(查询方法代表您执行)SELECT
- 使用 Cursor 的
moveToFirst
方法,测试它是否返回 true (以防万一,如果查询有效,则应始终返回单行) - 提取值(可能使用 Cursor 的
getString
方法作为字符串) - 如果 movetoFirst 返回 false (非常不可能),则将 String 设置为适当的值以指示未获得/提取任何内容。
- 在任何一种情况下,都使用光标的关闭方法(打开太多(如未关闭)光标会导致异常(类似于 1000))。
- 设置 Textview 的文本(可以作为 4 和 6 的一部分完成)
例子
这是一个非常基本的示例:-
启动时进入第一个活动 (MainActivity),准备名为clickMe的 TextView ,允许单击它并启动第二个活动 (MainActivity2),获取 DatabaseHelper 的实例,向chrono表添加一些行,(作弊并更改clickMe textview 显示平均值)。
如果单击clickMe Textview,则启动第二个活动并...
第二个活动获取它的数据库助手实例并将 TextView 设置为平均值。
为简洁起见(可以使用后退按钮返回)。
编码
数据库助手DBHelper.java
class DBHelper extends SQLiteOpenHelper {
private static final String DBNAME = "chrono.db"; /* name of the database file - change as fits */
private static final int DBVERSION = 1; /* version of the database - best to use 1 at first */
public static final String CHRONO_TABLENAME = "_chrono"; /* name of the table - change as fits underscore at start means no clash with SQLite keywords */
public static final String CHRONO_TABLE_ID_COLUMN = BaseColumns._ID; /* make the ID column use the android standard column name for the ID column */
public static final String CHRONO_TABLE_TIME_COLUMN = "time"; /* name of the time column */
private static SQLiteDatabase db;
private static volatile DBHelper instance_of_DBHelper;
private DBHelper(@Nullable Context context) {
super(context, DBNAME, null, DBVERSION);
db = this.getWritableDatabase(); /* Force initial open of the database when called - optional */
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + CHRONO_TABLENAME + "(" +
CHRONO_TABLE_ID_COLUMN + " INTEGER PRIMARY KEY," +
CHRONO_TABLE_TIME_COLUMN + " INTEGER DEFAULT 0" +
");");
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public static DBHelper getInstance_of_DBHelper(Context context) {
if (instance_of_DBHelper == null) {
instance_of_DBHelper = new DBHelper(context);
}
return instance_of_DBHelper;
}
public long insertChronoRow(long timeAsLong) {
ContentValues cv = new ContentValues();
cv.put(CHRONO_TABLE_TIME_COLUMN,timeAsLong);
return db.insert(CHRONO_TABLENAME,null,cv);
}
public String getAverageTime() {
String rv = "Cannot get Average????";
Cursor csr = db.query(
CHRONO_TABLENAME,
new String[]{"avg("+ CHRONO_TABLE_TIME_COLUMN +") AS "+ CHRONO_TABLE_TIME_COLUMN +""},
null,
null,
null,
null,
null,
null
);
if (csr.moveToFirst()) {
rv = csr.getString(csr.getColumnIndex(CHRONO_TABLE_TIME_COLUMN));
}
csr.close();
return rv;
}
}
- 请注意,这使用了单例方法,因此始终使用相同的实例。
MainActivity 的布局activity_main.xml :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/clickme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CLICK ME!" />
</LinearLayout>
第一个活动MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView clickMe;
DBHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clickMe = this.findViewById(R.id.clickme);
// Setup the TextView so that if clicked it starts the 2nd activity
clickMe.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,MainActivity2.class);
intent.putExtra("UNIQUE_KEY_FROM_MAINACTIVITY_VALUE1","a suitable values to be passed to the started activity");
startActivity(intent);
}
});
dbHelper = DBHelper.getInstance_of_DBHelper(this); /* Get an Instance of the Database helper */
dbHelper.insertChronoRow(60); /* 60 time units */
dbHelper.insertChronoRow(100); /* 100 time units */
dbHelper.insertChronoRow(110); /* 110 time untis */
clickMe.setText("CLICK ME!! - P.S. Average is now " + dbHelper.getAverageTime());
}
}
第二个活动activity_main2.xml的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity2">
<TextView
android:id="@+id/average"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Average as yet - if you see this then something is not right">
</TextView>
</LinearLayout>
最后是第二个活动MainActivity2.java
public class MainActivity2 extends AppCompatActivity {
TextView average;
DBHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
average = this.findViewById(R.id.average);
dbHelper = DBHelper.getInstance_of_DBHelper(this);
average.setText(dbHelper.getAverageTime());
}
}
结果
开始时:-
单击 TextView(如上图突出显示)并启动第二个活动时:-
推荐阅读
- django - 如果 html 发生更改,Django 停止重新启动服务器
- prometheus - 在普罗米修斯仪器的上下文中,我应该在更新指标值时使用所有普罗米修斯标签吗
- gitlab-ci - GitLab CI/CD 仅当在正确的分支上并且它有更改时才运行步骤
- mysql - 基于重复列更新列
- .htaccess - 使用 .htaccess/.htpasswd 限制页面后无法加载 CSS 文件
- xml - 将csv文件转换为多个xml文件
- c# - 如何从水晶报表“数据集报表”的设计者创建的报表中捕获水晶报表 SQL?
- javascript - 有条件地添加 babel core-js 的正确方法是什么
- java - Springboot本机查询不给出结果
- xamarin - 在 Xamarin.Android 中使用活动结果 API