哪里可以更全面、深入地理解带Context参数的实例化?
Where can I get a better understanding of the overall and indepth understanding of instantiation with Context parameters?
我试图解决这段代码中Context和类之间的联系以及我对这个概念的理解。 MainActivity.this
在这里不起作用。它带有周围的代码。
package com.Table;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import com.example.tablefreezepane.DatabaseHandler;
import com.example.tablefreezepane.MainActivity;
import java.util.ArrayList;
import java.util.List;
public class AsyncInsertData extends AsyncTask<String, String, String> {
DatabaseHandler databaseHandler;
String type;
long timeElapsed;
protected AsyncInsertData(String type){
this.type = type;
this.databaseHandler = new DatabaseHandler(MainActivity.this);
}
// @type - can be 'normal' or 'fast'
//@Override
//protected void onPreExecute() {
// super.onPreExecute();
// tvStatus.setText("Inserting " + editTextRecordNum.getText() + " records...");
//}
@Override
protected String doInBackground(String... aurl) {
try {
// get number of records to be inserted
int insertCount = 20;
// empty the table
databaseHandler.deleteRecords();
// keep track of execution time
long lStartTime = System.nanoTime();
if (type.equals("normal")) {
databaseHandler.insertNormal(insertCount);
} else {
databaseHandler.insertFast(insertCount);
}
// execution finised
long lEndTime = System.nanoTime();
// display execution time
timeElapsed = lEndTime - lStartTime;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String unused) {
Toast.makeText(getApplicationContext(),"This is an Android Toast Message", Toast.LENGTH_LONG).show();
//tvStatus.setText("Done " + choice + " inserting " + databaseHandler.countRecords() + " records into table: [" + this.databaseHandler.tableName + "]. Time elapsed: " + timeElapsed / 1000000 + " ms.");
}
}
阅读或复制代码不是问题。问题存在于this.databaseHandler = new DatabaseHandler(MainActivity.this);
语句中Context参数的整体思维模型中。行代码必须存在才能调用 databaseHandler
class.
中的方法
package com.example.tablefreezepane;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.widget.TextView;
public class DatabaseHandler extends SQLiteOpenHelper {
// for our logs
public static final String TAG = "DatabaseHandler.java";
public TextView tvstatus;
// database version
private static final int DATABASE_VERSION = 7;
// database name
protected static final String DATABASE_NAME = "NinjaDatabase2";
// table details
public String tableName = "locations";
public String fieldObjectId = "id";
public String fieldObjectName = "name";
public String fieldObjectDescription = "description";
// constructor
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// creating table
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "";
this.tvstatus.setText("Creating table");
sql += "CREATE TABLE " + tableName;
sql += " ( ";
sql += fieldObjectId + " INTEGER PRIMARY KEY AUTOINCREMENT, ";
sql += fieldObjectName + " TEXT, ";
sql += fieldObjectDescription + " TEXT ";
sql += " ) ";
db.execSQL(sql);
this.tvstatus.setText("Table created...");
// create the index for our INSERT OR REPLACE INTO statement.
// this acts as the WHERE name="name input" AND description="description input"
// if that WHERE clause is true, I mean, it finds the same name and description in the database,
// it will be REPLACEd.
// ELSE, what's in the database will remain and the input will be INSERTed (new record)
String INDEX = "CREATE UNIQUE INDEX locations_index ON "
+ tableName + " (name, description)";
db.execSQL(INDEX);
}
/*
* When upgrading the database, it will drop the current table and recreate.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS " + tableName;
db.execSQL(sql);
onCreate(db);
}
// insert data using transaction and prepared statement
public void insertFast(int insertCount) {
// you can use INSERT only
String sql = "INSERT OR REPLACE INTO " + tableName + " ( name, description ) VALUES ( ?, ? )";
SQLiteDatabase db = this.getWritableDatabase();
/*
* According to the docs http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
* Writers should use beginTransactionNonExclusive() or beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)
* to start a transaction. Non-exclusive mode allows database file to be in readable by other threads executing queries.
*/
//db.beginTransactionNonExclusive();
db.beginTransaction();
SQLiteStatement stmt = db.compileStatement(sql);
for(int x=1; x<=insertCount; x++){
stmt.bindString(1, "Name # " + x);
stmt.bindString(2, "Description # " + x);
stmt.execute();
stmt.clearBindings();
}
db.setTransactionSuccessful();
db.endTransaction();
}
// inserts the record without using transaction and prepare statement
public void insertNormal(int insertCount){
try{
SQLiteDatabase db = this.getWritableDatabase();
for(int x=1; x<=insertCount; x++){
ContentValues values = new ContentValues();
values.put(fieldObjectName, "Name # " + x);
values.put(fieldObjectDescription, "Description # " + x);
db.insert(tableName, null, values);
}
db.close();
}catch(Exception e){
e.printStackTrace();
}
}
// deletes all records
public void deleteRecords(){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("delete from "+ tableName);
db.close();
}
// count records
public int countRecords(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT count(*) from " + tableName, null);
cursor.moveToFirst();
int recCount = cursor.getInt(0);
cursor.close();
db.close();
return recCount;
}
}
任何指导、图形模型链接以及 this.databaseHandler = new DatabaseHandler(MainActivity.this);
语句的构建方式都将不胜感激。
行:
this.databaseHandler = new DatabaseHandler(MainActivity.this);
期望在构造函数中有一个有效的 Context
。 Activity
extends ContextThemeWrapper
因此是要传递的有效对象,但对象中的实际上下文必须有效。
您似乎从 Activity
复制了代码,所有这些代码都包含在 MainActivity
对象中,当 MainActivity
从框架创建时,上下文是有效的。
如果将 Activity
实例化为常规 class,它将被创建,但 Context
将无效。 Android 框架必须实例化它,并在 class 的构造期间为其提供有效的 Context
。您无法创建自己的有效 Context
,因为 Android 需要定义它。
这是一个很好的 post 关于 Context
是什么:
What is 'Context' on Android?
我不知道描述或解释它的图形。它有点抽象,因为它涉及有关 Android 环境的大量信息,包括一些视觉方面(如屏幕信息)和非视觉方面(文件位置、安全性、权限等)。
我试图解决这段代码中Context和类之间的联系以及我对这个概念的理解。 MainActivity.this
在这里不起作用。它带有周围的代码。
package com.Table;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import com.example.tablefreezepane.DatabaseHandler;
import com.example.tablefreezepane.MainActivity;
import java.util.ArrayList;
import java.util.List;
public class AsyncInsertData extends AsyncTask<String, String, String> {
DatabaseHandler databaseHandler;
String type;
long timeElapsed;
protected AsyncInsertData(String type){
this.type = type;
this.databaseHandler = new DatabaseHandler(MainActivity.this);
}
// @type - can be 'normal' or 'fast'
//@Override
//protected void onPreExecute() {
// super.onPreExecute();
// tvStatus.setText("Inserting " + editTextRecordNum.getText() + " records...");
//}
@Override
protected String doInBackground(String... aurl) {
try {
// get number of records to be inserted
int insertCount = 20;
// empty the table
databaseHandler.deleteRecords();
// keep track of execution time
long lStartTime = System.nanoTime();
if (type.equals("normal")) {
databaseHandler.insertNormal(insertCount);
} else {
databaseHandler.insertFast(insertCount);
}
// execution finised
long lEndTime = System.nanoTime();
// display execution time
timeElapsed = lEndTime - lStartTime;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String unused) {
Toast.makeText(getApplicationContext(),"This is an Android Toast Message", Toast.LENGTH_LONG).show();
//tvStatus.setText("Done " + choice + " inserting " + databaseHandler.countRecords() + " records into table: [" + this.databaseHandler.tableName + "]. Time elapsed: " + timeElapsed / 1000000 + " ms.");
}
}
阅读或复制代码不是问题。问题存在于this.databaseHandler = new DatabaseHandler(MainActivity.this);
语句中Context参数的整体思维模型中。行代码必须存在才能调用 databaseHandler
class.
package com.example.tablefreezepane;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.widget.TextView;
public class DatabaseHandler extends SQLiteOpenHelper {
// for our logs
public static final String TAG = "DatabaseHandler.java";
public TextView tvstatus;
// database version
private static final int DATABASE_VERSION = 7;
// database name
protected static final String DATABASE_NAME = "NinjaDatabase2";
// table details
public String tableName = "locations";
public String fieldObjectId = "id";
public String fieldObjectName = "name";
public String fieldObjectDescription = "description";
// constructor
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// creating table
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "";
this.tvstatus.setText("Creating table");
sql += "CREATE TABLE " + tableName;
sql += " ( ";
sql += fieldObjectId + " INTEGER PRIMARY KEY AUTOINCREMENT, ";
sql += fieldObjectName + " TEXT, ";
sql += fieldObjectDescription + " TEXT ";
sql += " ) ";
db.execSQL(sql);
this.tvstatus.setText("Table created...");
// create the index for our INSERT OR REPLACE INTO statement.
// this acts as the WHERE name="name input" AND description="description input"
// if that WHERE clause is true, I mean, it finds the same name and description in the database,
// it will be REPLACEd.
// ELSE, what's in the database will remain and the input will be INSERTed (new record)
String INDEX = "CREATE UNIQUE INDEX locations_index ON "
+ tableName + " (name, description)";
db.execSQL(INDEX);
}
/*
* When upgrading the database, it will drop the current table and recreate.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS " + tableName;
db.execSQL(sql);
onCreate(db);
}
// insert data using transaction and prepared statement
public void insertFast(int insertCount) {
// you can use INSERT only
String sql = "INSERT OR REPLACE INTO " + tableName + " ( name, description ) VALUES ( ?, ? )";
SQLiteDatabase db = this.getWritableDatabase();
/*
* According to the docs http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
* Writers should use beginTransactionNonExclusive() or beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)
* to start a transaction. Non-exclusive mode allows database file to be in readable by other threads executing queries.
*/
//db.beginTransactionNonExclusive();
db.beginTransaction();
SQLiteStatement stmt = db.compileStatement(sql);
for(int x=1; x<=insertCount; x++){
stmt.bindString(1, "Name # " + x);
stmt.bindString(2, "Description # " + x);
stmt.execute();
stmt.clearBindings();
}
db.setTransactionSuccessful();
db.endTransaction();
}
// inserts the record without using transaction and prepare statement
public void insertNormal(int insertCount){
try{
SQLiteDatabase db = this.getWritableDatabase();
for(int x=1; x<=insertCount; x++){
ContentValues values = new ContentValues();
values.put(fieldObjectName, "Name # " + x);
values.put(fieldObjectDescription, "Description # " + x);
db.insert(tableName, null, values);
}
db.close();
}catch(Exception e){
e.printStackTrace();
}
}
// deletes all records
public void deleteRecords(){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("delete from "+ tableName);
db.close();
}
// count records
public int countRecords(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT count(*) from " + tableName, null);
cursor.moveToFirst();
int recCount = cursor.getInt(0);
cursor.close();
db.close();
return recCount;
}
}
任何指导、图形模型链接以及 this.databaseHandler = new DatabaseHandler(MainActivity.this);
语句的构建方式都将不胜感激。
行:
this.databaseHandler = new DatabaseHandler(MainActivity.this);
期望在构造函数中有一个有效的 Context
。 Activity
extends ContextThemeWrapper
因此是要传递的有效对象,但对象中的实际上下文必须有效。
您似乎从 Activity
复制了代码,所有这些代码都包含在 MainActivity
对象中,当 MainActivity
从框架创建时,上下文是有效的。
如果将 Activity
实例化为常规 class,它将被创建,但 Context
将无效。 Android 框架必须实例化它,并在 class 的构造期间为其提供有效的 Context
。您无法创建自己的有效 Context
,因为 Android 需要定义它。
这是一个很好的 post 关于 Context
是什么:
What is 'Context' on Android?
我不知道描述或解释它的图形。它有点抽象,因为它涉及有关 Android 环境的大量信息,包括一些视觉方面(如屏幕信息)和非视觉方面(文件位置、安全性、权限等)。