哪里可以更全面、深入地理解带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);

期望在构造函数中有一个有效的 ContextActivity extends ContextThemeWrapper 因此是要传递的有效对象,但对象中的实际上下文必须有效。

您似乎从 Activity 复制了代码,所有这些代码都包含在 MainActivity 对象中,当 MainActivity 从框架创建时,上下文是有效的。

如果将 Activity 实例化为常规 class,它将被创建,但 Context 将无效。 Android 框架必须实例化它,并在 class 的构造期间为其提供有效的 Context。您无法创建自己的有效 Context,因为 Android 需要定义它。

这是一个很好的 post 关于 Context 是什么:

What is 'Context' on Android?

我不知道描述或解释它的图形。它有点抽象,因为它涉及有关 Android 环境的大量信息,包括一些视觉方面(如屏幕信息)和非视觉方面(文件位置、安全性、权限等)。