2015-02-27 4 views
0

Мне нужно создать объект для SQLiteOpenHelper из потока AsyncTask. Если я использую this как параметр Context, я получаю ошибку - it cannot be applied.Не удается создать объект для SQLiteOpenHelper из потока AsyncTask?

Вот мои классы:

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, в третьем комментарии ниже этот ответ объяснил то же самое в коде.

EDIT:

Это EDIT не сильно связан с вопросом. ZygoteInit помогает мне с общим подходом к моей проблеме.

Это то, что я делаю. Я новичок в Android. Не уверен, что это может быть проще.

Я хочу, чтобы часть кода выполнялась каждые несколько часов. Итак, я использовал класс AlarmManager. Я рассматривал все связанные с этим вещи. Класс AlarmReceiver вызывается каждые 4 часа. Я хочу поместить свой код в этот класс. Но поскольку код включает Networking, то есть загружает некоторые данные, я узнал, что рекомендуется использовать AsyncTask. Итак, я создал еще один класс Parsing, который расширяет AsyncTask. Теперь мне нужно сохранить данные, полученные во время этой операции в сети, которая выполняется в классе Parsing. Итак, я создал класс MySQLiteHelper.

Могу ли я сделать его более простым человеком? Моя цель: выполнить фоновое сетевое взаимодействие каждые несколько часов, в которое входит база данных.

Первоначально я использовал service. Но я хочу, чтобы мой код выполнялся каждые четыре часа, даже если приложение закрыто. Итак, я прочитал here, чтобы использовать диспетчер аварийных сигналов.

ответ

1

Если AsyncTask класс определяется внутри Activity, а затем использовать MyActivity.this в качестве Context, иначе передайте экземпляр Context в конструкторе.

EDIT:

Прочитав ваш вопрос, я понял ваше требование. Вместо использования BroadcastReceiver создайте Service с PendingIntent (т. Е. Используйте getService() вместо getBroadcast()) и выполните операции веб-службы и базы данных. С Service вы получите действительный экземпляр this для Context.

+0

Что такое экземпляр контекста в моем случае, пожалуйста? – Nikhil

+0

@ZygoteInit: я думаю, что 'Parsing' является отдельным классом, поэтому' MyActivity.this' не будет работать. OP нужно передать контекст из Activity в 'Parsing', затем из' Parsing' в 'MySQLiteHelper' –

+1

@nikhil: добавить' private Context mContext ; публичный анализ (контекст mContext) {this.mContext = mContext} 'в классе« Parsing »и создание объекта« Parsing »из Activity, передавая« MyActivity.this »как« Парсинг objParsing = новый парсинг (MyActivity.this); objParsing.execute(); ' –

1

создать поле 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 
    } 

    } 

Но я хотел бы предложить, что вместо создания instance из MySqliteHelper на onPreExecute() методе вы создаете instance о том, что в вашем activity/fragment или что вы используете, а затем получить доступ к нему на 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 чем создать публичного метод, где вы можете получить context из и call этот способ если вы хотите получить это context. Как так:

public Context geContext(){ 
return mContext 
} 

Если вы столкнулись с проблемой создания экземпляра MySqliteHelper для некоторых reasen чем сделать mContext public static Context mContext и доступ к нему непосредственно, как MySQliteHelper.mContext

+0

Не работает! mContext не может быть подключен к классу Parsing. – Nikhil

+0

@nikhil см. Мой обновленный ответ для доступа к нему из другого класса – hrskrs

+0

Хорошая работа @hrskrs Но я все еще получаю ту же ошибку, поскольку я не могу использовать частный член другого класса в классе Parsing. – Nikhil

1

Я думаю, что вы хотите передать ссылку на класс ParsingActivty к 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 
    } 

} 
0

Либо передайте контекст в конструкторе вашей AsyncTask, либо используйте статическую переменную в вашем классе Application для доступа к нему (установите sMyInstace = this;). Однако первое решение предпочтительнее.

Смежные вопросы