I have two classes; the first is an asynctask and the other is an ConnectionDetector class
which contains the code shown here (3rd step),
public class myTask extends AsyncTask<String,Void,String>{
private Context context;
ConnectionDetector connectiondetector = new ConnectionDetector(context);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//CHECK INTERNET CONNECTION
if(connectiondetector.isConnectingToInternet()){ //method from connectiondetector.java
//do something
}
}
when I run this code I get a null pointer exception at the if statement.
is it because of the context, how do I fix this?
the asynctask class is called from a different activity ( partosrecord.class )
Pass context to the constructor of oyur asynctask from your activity class
new myTask(ActivityName.this).execute(params);
In your asynctask
public class myTask extends AsyncTask<String,Void,String>{
ConnectionDetector connectiondetector
Context mcontext;
public myTask(Context context)
{
mcontext= context;
connectiondetector = new ConnectionDetector(mcontext);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if(connectiondetector.isConnectingToInternet()){
//dosomething
}
}
Code where u call asynctask:-
myTask site = new myTask(this);
site.execute();
or use this below code on AsyncTask
public class myTask extends AsyncTask<String,Void,String>{
private Context context;
ConnectionDetector connectiondetector
public myTask(Context con)
{
context=con;
connectiondetector = new ConnectionDetector(context);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//CHECK INTERNET CONNECTION
if(connectiondetector.isConnectingToInternet()){ //method from connectiondetector.java
//do something }
}
Related
I have a class that is used for various ASyncTasks. Sometimes, I need to hide certain buttons, or views or whatever based upon the Activity or action. The object needing visibility set can vary.
MyAsyncTask
public class MyAsyncTask extends AsyncTask<String, Void, JSONObject> {
private ProgressBar mProgressBar;
public ASynceResponse delegate = null;
public MyAsyncTask() {
this.delegate = delegate;
this.mProgressBar = progressBar;
}
#Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected JSONObject doInBackground(String... params) {
return;
}
#Override
protected void onPostExecute(JSONObject data) {
mProgressBar.setVisibility(View.GONE);
delegate.processResults(data);
}
public interface ASyncResponse {
void processResults(JSONObject data);
}
}
I usually call it by:
new MyAsyncTask(this, mProgressBar).execute("Something","Something Else",null);
Which I pass in a ProgressBar in the Activity that shows the background action is happening.
But I want more. I want to Overide my classes onPreExecute and onPostExecute to hide/show other items too.
Is that possible?
But I am trying to find a way to Overide the onPreExecute to hide anytype (or many types) views.
Is something like this possible?
MyAsyncTask myAsyncTask = new MyAsyncTask(new onPreExecute(
// hide a view
));
You can do that using interface.
public class MyAsyncTask extends AsyncTask<String, Void, JSONObject> {
private ProgressBar mProgressBar;
public ASynceResponse delegate = null;
public MyAsyncTask() {
this.delegate = delegate;
this.mProgressBar = progressBar;
}
#Override
protected void onPreExecute() {
delegate.myOnPreExecute();
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected JSONObject doInBackground(String... params) {
return;
}
#Override
protected void onPostExecute(JSONObject data) {
mProgressBar.setVisibility(View.GONE);
delegate.processResults(data);
}
public interface ASyncResponse {
void processResults(JSONObject data);
void myOnPreExecute();
}
}
Demo class example
class Demo implements ASyncResponse{
.....
void processResults(JSONObject data){
....
}
void myOnPreExecute(){
// do your stuff for pre execute
}
}
I have this setup
MainActivity Class creates BTHandler which is a utility class. It passes activity context and application context.
public class MainActivity extends Activity implements View.OnClickListener{
protected void onCreate(Bundle savedInstanceState) {
...
currentBT = new BTHandle(this, MainActivity.this);
}
public Handler handler = new Handler() {
#Override
public void handleMessage(android.os.Message msg) {
...
super.handleMessage(msg);
}
};
}
This is the Utiliy class. It uses both context for some computation and when is required it creates ConnectThread, to start a connection with a BT device. It passes the activity context so ConnectThread can send a message through the Handler.
class BTHandle {
private final Context mainActivityContext;
private final Activity mainActivity;
...
public BTHandle(final Context context, final Activity activity){
mainActivityContext = context;
mainActivity = activity;
}
f(){
ConnectThread connectAsClient = new ConnectThread(mainActivityContext, BTDevice, mBluetoothAdapter, BTUuid);
new Thread(connectAsClient).start();
}
}
And Finally here comes the error. This is ConnectThread. I want to send a message from here to MainActivity. But compiler says it cant resolve handler. So I'm guessing the context doesn't come trough it.
public class ConnectThread implements Runnable {
private final Context mainActivity;
public ConnectThread(Context context, BluetoothDevice device, BluetoothAdapter adapter, UUID BT_UUID) {
...
mainActivity = context;
}
#Override
public void run() {
...
Message completeMessage = mainActivity.handler.obtainMessage(555, "CONNECTED");
completeMessage.sendToTarget();
}
}
How can I pass the context in the right way so ConnectThread can see handler?
You can either pass in the MainActivity object all the way down to ConnectRunnable i.e :
private final MainActivity mainActivity;
public ConnectThread(MainActivity context, BluetoothDevice device,
BluetoothAdapter adapter, UUID BT_UUID) {
...
mainActivity = context;
}
Or change your call to:
Message completeMessage =
((MainActivity)(Activity)mainActivity)).handler.obtainMessage(555, "CONNECTED");
Also, your handler is bound to leak memory.
Have a look at this for the fix: How to Leak a Context: Handlers & Inner Classes
You can also define a public and static MainActvity variable and use it in your other class :
public class MainActivity extends Activity implements View.OnClickListener{
public static MainActivity mainActivity;
protected void onCreate(Bundle savedInstanceState) {
...
mainActivity = this;
currentBT = new BTHandle(this, MainActivity.this);
}
public Handler handler = new Handler() {
#Override
public void handleMessage(android.os.Message msg) {
...
super.handleMessage(msg);
}
};
}
and in your other class :
public class ConnectThread implements Runnable {
private MainActivity mainActivity;
public ConnectThread(Context context, BluetoothDevice device, BluetoothAdapter adapter, UUID BT_UUID) {
...
mainActivity = MainActivity.mainActivity;
}
#Override
public void run() {
...
Message completeMessage = mainActivity.handler.obtainMessage(555, "CONNECTED");
completeMessage.sendToTarget();
}
}
I want to generate a TextView inside AsyncTask's onPostExecute like this :
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String mymeaning) {
TextView myView = new TextView(this);
myView.setText(Html.fromHtml(myString));
}
}
But it gives error telling me that this cannot be applied to AsyncTranslator.
Can you tell me how I can generate textViews inside AsyncTask onPostExecute? Thanks.
From the documentation the possible constructors are
TextView(Context context)
TextView(Context context, AttributeSet attrs)
TextView(Context context, AttributeSet attrs, int defStyleAttr)
TextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
but you are doing
TextView myView = new TextView(this);
inside AsyncTranslator which is incorrect.
You can easily create a TextView inside your AsyncTask if you have a reference to your context. See this thread to get a reference to your context.
EDIT
It seems that you already have a reference to your context, so just do
TextView myView = new TextView(context);
In AsyncTask you shouldn't make operations on base UI thread and here you are trying to do it. Try to create new Interface which lets you to pass the result.
public interface asyncTaskInterface {
public void printEditText();
}
Then in your AsyncTask:
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
public asyncTaskInterface delegate;
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "Please wait.", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String mymeaning) {
delegate.printEditText();
}
}
In your result class you have to implement the interface and pass the class to your async task as delegate:
public class myClassActivity implements asyncTaskInterface ...
before you will call async task assign the delegate:
AsyncTranslator translator = new AsyncTranslator();
translator.delegate = this;
translator.execute();
At the end in your activity overwrite the method from your intrface and build in it the TextView.
First create an interface like this:
public interface onTextViewCreatedListener {
public void onTextViewCreated(TextView tv);
}
Then change your AsyncTranslator class like this
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
private onTextViewCreatedListener onTextViewCreatedListener;
public AsyncTranslator(onTextViewCreatedListener onTextViewCreatedListener){
this.onTextViewCreatedListener = onTextViewCreatedListener;
}
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "Please wait.", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String mymeaning) {
//since you have passed context to Toast in onPreExecute use that context here also.
TextView myView = new TextView(context);
myView.setText(Html.fromHtml(myString));
if(onTextViewCreatedListener!=null){
onTextViewCreatedListener.onTextViewCreated(myView);
}
}
}
and then use AsyncTranslator class in your activity class like this:
AsyncTranslator asyncTranslator = new AsyncTranslator(new onTextViewCreatedListener() {
#Override
public void onTextViewCreated(TextView tv) {
//you can use your created textview here
}
});
that context should be passed from your activity where you are going to call aynctask.execute()
I'm calling an Async class from my main activity class. When the POST has been executed I want to return the result back to the main activity.
public class MainActivity extends Activity implements OnClickListener, AsyncResponse{
public Context context;
PostKey asyncTask = new PostKey(context);
public void onCreate(Bundle savedInstanceState) {
asyncTask.delegate = this;
}
public void onClick(View v) {
asyncTask.delegate = this;
new PostKey(context).execute(keyValue);
}
public void processFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
Log.d("Result", output);
}
}
public class PostKey extends AsyncTask<String, String, String> {
public AsyncResponse delegate = null;
public Context context;
public PostKey(Context context){
this.context = context.getApplicationContext();
}
#Override
protected String doInBackground(String... params) {
return postData(params[0]);
}
#Override
protected void onPostExecute(String result){
this.context = context.getApplicationContext();
delegate = (AsyncResponse) context;
}
delegate.processFinish(result);
}
public interface AsyncResponse {
void processFinish(String output);
}
Whenever I try to run the app I immediately get a fatal error caused by a nullpointer exception. The nullpointer refers to the following:
public PostKey(Context context){
this.context = context.getApplicationContext();
}
&
PostKey asyncTask = new PostKey(context);
In the second case I can get that context is empty, but I have to pass the variable here.
Activity is already a Context, so you don't to keep a reference to it. Just use this. On the other hand the Activity has to go through its lifecycle before you can use the context. Remove
public Context context;
PostKey asyncTask = new PostKey(context);
and add
PostKey asyncTask = new PostKey(this);
in your onCreate. And please, add super.onCreate(savedInstanceState); as first thing in your onCreate
Hello Oryna you passing null context value as in parameter just replace these lines with this
new PostKey(context).execute(keyValue);
to
new PostKey(MainActivity.this).execute(keyValue);
and the constructor for the async task replace the code
public PostKey(Context context){
this.context = context.getApplicationContext();
}
with
public PostKey(Context context){
this.context = context;
}
try to use this.context = getApplicationContext(); instead
I have a class with DownloadPicture method which is executing an AsyncTask. The class is not a subclass of class MainActivity extends Activity. How can I show ProgressDialogs by using DownloadPicture method? I think I can pass MainActivity.this to class conatructor, but is there any other way?
Try this way,hope this will help you to solve your problem.
Pass your activity context to DownloadPicture class in constructor and initialize ProgressDialogs in onPreExecute() :
public class ProgressDialogs extends AsyncTask<Void,Void,Void>{
private Context context;
private ProgressDialog progressDialog;
public ProgressDialogs(Context context){
this.context=context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(context, "dialog title","dialog message", true);
}
#Override
protected Void doInBackground(Void... params) {
// do you background code here
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(progressDialog!=null && progressDialog.isShowing()){
progressDialog.dismiss();
}
}
}
Use an Interface to callback to activity from your AsyncTask. And you can do whatever with ProgressDialog from your activity. Can explain in detail if you can provide your code sample.