无法从 AsyncTask 线程为 SQLiteOpenHelper 创建对象?

Cannot create an object for SQLiteOpenHelper from AsyncTask thread?

我必须从 AsyncTask 线程为 SQLiteOpenHelper 创建一个对象。 如果我使用 this 作为 Context 参数,我会得到一个错误 - it cannot be applied.

这是我的 classes :

MySQLiteHelper.java

public class MySQLiteHelper extends SQLiteOpenHelper {

  public MySQLiteHelper(Context context) {

    // the constructor takes Context as argument
}

}

Parsing.java

public class Parsing extends AsyncTask<Void, Void, Void> {

protected void onPreExecute() {

  MySQLiteHelper obj  = new MySQLiteHelper(this); 
  //cannot create  this object. 
 // which `Context` should I pass as an argument

    }

    // some code
}

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {


        Parsing obj = new Parsing(context);

        obj.execute();

    }
}

回答我的问题: ZygoteInit 在标记答案中建议的方法已解决。 ρяσѕρєя K,在下面的第 3 条评论中,该答案在代码中解释了相同的内容。

编辑:

此编辑与问题关系不大。 ZygoteInit 正在帮助我解决问题的整体方法。

这就是我正在做的。我是 Android 的新手。不确定这是否可以更简单。

我想要每隔几个小时执行一段代码。所以,我用了AlarmManagerclass。我处理了上面所有相关的东西。 AlarmReceiver class 每 4 小时调用一次。我想把我的代码放在 class 中。但由于代码涉及网络,即下载一些数据,我了解到建议使用 AsyncTask。因此,我创建了另一个扩展 AsyncTask 的 class Parsing。现在,我需要存储在 Parsing class 中执行的网络操作期间获得的数据。所以,我创建了 MySQLiteHelper class.

伙计们,我可以让它更简单吗? 我的目标:每隔几个小时执行一次后台网络操作,涉及数据库。

最初我使用service。但是,我希望我的代码每四个小时执行一次,即使应用程序已关闭也是如此。所以,我阅读 here 以使用警报管理器。

创建一个字段 private Context mContext 并在您的 constructor 中将其分配给 context 作为:this.mContext = context 并使用 mContext 而不是 this

从你的例子(硬编码没有测试,所以你只是理解逻辑):

    public class MySQLiteHelper extends SQLiteOpenHelper {

    private Context mContext;

      public MySQLiteHelper(Context context) {

        this.mContext = context;
    }

    public class Parsing extends AsyncTask<Void, Void, Void> {

      protected void onPreExecute() {

      MySQLiteHelper obj  = new MySQLiteHelper(mContext); 
      //cannot create  this object. 
      // which `Context` should I pass as an argument

      }

        // some code
    }

   }

但我建议不要在 onPreExecute() 方法上创建一个 MySqliteHelperinstance,而是在 activity/fragment 中创建一个 instance或者你使用的任何东西,然后在 onPreExecute() 上访问它,就像这样:

public YourClass extends Activity{ 
private MySQLiteHelper obj;
  @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    obj  = new MySQLiteHelper(this); 
}
 private class Parsing extends AsyncTask<Void, Void, Void> { 
  //access obj here
  obj.whateverMethodYouWantToAccess
 }
}

如果在某些特定情况下你想从另一个 class 访问它而不是创建一个 public 方法 在那里你可以获得 context 并在您想要获取 context 时调用该方法。像这样:

public Context geContext(){
 return mContext
}

如果您在创建 MySqliteHelper 实例时遇到问题,而不是创建 mContext public static Context mContext 并像 MySQliteHelper.mContext

那样直接访问它

如果您的 AsyncTask class 定义在 Activity 内,则使用 MyActivity.this 作为 Context,否则传递 Context构造函数中的实例。

编辑:

看了你的问题,明白了你的要求。不要使用 BroadcastReceiver,而是使用 PendingIntent 创建 Service(即使用 getService() 而不是 getBroadcast())并在其中执行 Web 服务和数据库操作.从 Service 您将获得 Context.

的有效 this 实例

我认为您想将 ParsingActivty class 引用传递给 MySQLiteHelper,您将为此执行此操作

 public class ParsingActivty extends Activity 
 {
 Context context;
 protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
     context=this;
 }

并在 Parsing.java

public class Parsing extends AsyncTask<Void, Void, Void> {

protected void onPreExecute() {

  MySQLiteHelper obj  = new MySQLiteHelper(context); 

}

// some code
}

并且在MySQLiteHelper.java

public class MySQLiteHelper extends SQLiteOpenHelper {

  public MySQLiteHelper(Context context) {

// the constructor takes Context as argument
  }

}

要么在 AsyncTask 的构造函数中传递上下文,要么在应用程序中使用静态变量 class 来访问它(设置 sMyInstace = this;)。不过,第一种解决方案更可取。