Is it possible to pass a fragment in a constructor? - android

I am trying to pass my Fragment to an ASyncTask class so that I can update a widget or two in the fragment once the task completes. Here's what I'm dealing with:
public class LoginFragment extends Fragment {
Button loginButton;
TextView loginErrorMsg;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.loginfragment, container, false);
}
public OnClickListener loginListener = new OnClickListener() {
#Override
public void onClick(View v) {
Log.v("LoginF", "onclick");
ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Logging in...");
LoginTask loginTask = new LoginTask((Polling) getActivity(), progressDialog);
loginTask.execute();
}
};
And the LoginTask:
public class LoginTask extends AsyncTask<String, Void, Integer> {
private ProgressDialog progressDialog;
private Polling activity;
private int id = -1;
private JSONParser jsonParser;
private static String loginURL = "http://davidjkelley.net/android_api/";
private static String registerURL = "http://davidjkelley.net/android_api/";
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";
TextView loginErrorMsg = (EditText)activity.findViewById(R.id.loginErrorMsg);
EditText userName = (EditText)activity.findViewById(R.id.emailEditText);
EditText passwordEdit = (EditText)activity.findViewById(R.id.passEditText);
public LoginTask(Polling activity, ProgressDialog progressDialog)
{
this.activity = activity;
this.progressDialog = progressDialog;
}
So I would like to add a third parameter to the constructor of LoginTask, essentially an instance of my LoginFragment. My goal is to update either a TextView or put up a Toast on the screen to clarify whether login succeeds or fails: as right now, the user has no way of telling how the login proceeded. Ideas?

As curious says you don't want to be passing Fragments around (they have a 'link' to the activity which is a context and passing contexts is baaad)
You want to pass a small object that can help you call back from your Task to your Fragment.
I would also use an interface. Here's my example:
Fragment:
public class LoginFragment extends Fragment implements OnClickListener, OnLoginListener{
Button loginButton;
TextView loginErrorMsg;
private ProgressDialog progressDialog;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Logging in...");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_login, container, false);
loginButton = v.findViewById(R.id.button);
loginButton.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
Log.v("LoginF", "onclick");
progressDialog.show();
LoginTask loginTask = new LoginTask(this);
loginTask.execute();
break;
default:
break;
}
}
#Override
public void onLoginSuccess() {
progressDialog.dismiss();
// Yayy
}
#Override
public void onLoginFailure() {
progressDialog.dismiss();
// Boo
}
}
The ASyncTask:
public class LoginTask extends AsyncTask<String, Void, Integer> {
private final OnLoginListener listener;
public interface OnLoginListener{
public void onLoginSuccess();
public void onLoginFailure();
}
public LoginTask(OnLoginListener listener) {
this.listener = listener;
}
#Override
protected Integer doInBackground(String... params) {
try{
// Something
} catch (SomeException e){
listener.onLoginFailure();
}
return null;
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
listener.onLoginSuccess();
}
}
If you get your head around interfaces your world will open up and your code will look less like the amazon jungle and more like a well organised garden ;-)

I suggest you use a Callback interface for this purpose. It is generally not a good idea to pass in UI-specific (actually, context-specific) objects to an AsyncTask.
Here's what I suggest. With this approach, you don't even need to pass in your Fragment around.
Disclaimer: I have not actually tried running this code - just typed it off the top of my head. So it may not even compile - it is just intended to be a guide.
interface LoginCallback{
void onLoginSuccess();
void onLoginFailure();
}
//onCreate code
TextView loginErrorMsg = (EditText)activity.findViewById(R.id.loginErrorMsg);
EditText userName = (EditText)activity.findViewById(R.id.emailEditText);
EditText passwordEdit = (EditText)activity.findViewById(R.id.passEditText);
LoginTask loginTask = new LoginTask(new LoginCallback(){
#Override
protected void onLoginSuccess(){
//Update UI
}
#Override
protected void onLoginFailure(){
//Update UI
}
});
loginTask.execute();
//LoginTask code.
public class LoginTask extends AsyncTask<String, Void, Integer> {
LoginCallback callback;
ProgressDialog progressDialog;
public LoginTask(LoginCallback callback){
this.callback = callback;
#Override protected void onPreExecute(){
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Logging in...");
}
#Override
protected Integer doInBackground(String... params){
//Do you login logic here.
}
#Override
protected void onPostExecute(Integer result) {
progressDialog.dismiss();
if(loginSuccess){
callback.onLoginSuccess();
} else {
callback.onLoginFailure();
}
}
}
}

Related

how to synchronise Between class controller contains AsyncTask and fragment

I am very very tired
I can't change visibility or an object in the fragment from the class controller
exmple addIteamsAutomatic.progressBar.setVisibility(View.GONE); return nullpointer
FragmentAddIteamsAutomatic :
public class FragmentAddIteamsAutomatic extends Fragment {
private EditText ssid, paswd;
public TextView afichage;
public Button parainage;
public Button validation;
public ProgressBar progressBar ;
public LinearLayout linearLayoutParm;
public static String sSSID,pWD;
private ControllerAddIteam controleAdd=null;
public FragmentAddIteamsAutomatic()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.add_iteams_automatic, container, false);
controleAdd.getInstance(getActivity());
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
ssid = (EditText) view.findViewById(R.id.ssid);
paswd = (EditText) view.findViewById(R.id.password);
parainage = (Button) view.findViewById(R.id.btnParainage);
validation = (Button) view.findViewById(R.id.btnValid);
afichage = (TextView) view.findViewById(R.id.affichage);
linearLayoutParm = (LinearLayout) view.findViewById(R.id.linearLayParam);
progressBar.setVisibility(View.GONE);
afichage.setVisibility(View.GONE);
validation.setVisibility(View.GONE);
parainage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sSSID = ssid.getText().toString();
pWD = paswd.getText().toString();
if (sSSID.equals(""))
Toast.makeText(getActivity(), "Vous Dever Remplir Tous les champs", Toast.LENGTH_LONG).show();
else
parainer();
}
});
validation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
controleAdd.addSwitchToBase();
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
ControllerAddIteam.accesDistant.send("getIteams", new JSONArray());
// finish();
}
});
return view;
}
private void parainer(){
controleAdd.getInstanceExecuteHandle();
}
}
ControllerAddIteam :
public class ControllerAddIteam {
private static ControllerAddIteam instanceAdd = null;
private static Context context;
private static WifiUtils wifiUtils;
public static String SSID = null;
public static AccesDistant accesDistant;
public static Handler mHandler;
public static final ControllerAddIteam getInstance(Context context) {
if (context != null)
ControllerAddIteam.context = context;
if (ControllerAddIteam.instanceAdd == null) {
ControllerAddIteam.instanceAdd = new ControllerAddIteam();
accesDistant = new AccesDistant();
}
return ControllerAddIteam.instanceAdd;
}
public static void getInstanceExecuteHandle() {
new ParainageHandle().execute();
}
static class ParainageHandle extends AsyncTask<String, String, String> {
FragmentAddIteamsAutomatic addIteamsAutomatic=new FragmentAddIteamsAutomatic();
#Override
protected void onPreExecute() {
super.onPreExecute();
addIteamsAutomatic.progressBar.setVisibility(View.GONE);
addIteamsAutomatic.afichage.setVisibility(View.GONE);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
addIteamsAutomatic.progressBar.setVisibility(View.GONE);
if(s.equals("valid"))
{
addIteamsAutomatic.linearLayoutParm.setVisibility(View.GONE);
addIteamsAutomatic.validation.setVisibility(View.VISIBLE);
addIteamsAutomatic.parainage.setVisibility(View.GONE);
}
else if(s.equals("notvalid"))
{
addIteamsAutomatic.parainage.setVisibility(View.VISIBLE);
}
}
#Override
protected void onProgressUpdate(String... values) {
addIteamsAutomatic.afichage.setVisibility(View.VISIBLE);
addIteamsAutomatic.progressBar.setVisibility(View.VISIBLE);
if (values[0].equals("actwifi")) {
if (values[1].equals("true"))
addIteamsAutomatic.afichage.setText("WIFI DEJA ACTIVEE");
else
addIteamsAutomatic.afichage.setText("ACTIVATION WIFI EN COURS...");
} else if (values[0].equals("scan"))
addIteamsAutomatic.afichage.setText("START SCAN FOR Iteams STiTo ... Please Wait");
else if (values[0].equals("find"))
addIteamsAutomatic.afichage.setText("STiTo : "+getTypeFromSsid(SSID)+" DETECTEE : "+SSID);
else if (values[0].equals("connect"))
addIteamsAutomatic.afichage.setText("CONNECTION WITH " + SSID + "En cours ...");
else if (values[0].equals("connectOk"))
addIteamsAutomatic.afichage.setText("CONNECTION WITH " + SSID + "ETABLISHED");
else if (values[0].equals("connectKo"))
addIteamsAutomatic.afichage.setText("PROBLEM OF CONNECTION WITH " + SSID);
else if (values[0].equals("config")) {
addIteamsAutomatic.afichage.setText("SENDING OF CONFIGURATION TO: "+getTypeFromSsid(SSID)+"AND SAVING DATA");
accesDistant.sendConfig(addIteamsAutomatic.sSSID,addIteamsAutomatic.pWD);
....
You declare fragment in AsyncTask and doesn't call replace or add, it mean this fragment never show and it not call onCreateView
FragmentAddIteamsAutomatic addIteamsAutomatic=new FragmentAddIteamsAutomatic();
Maybe you should pass reference addIteamsAutomatic to class ControllerAddIteam. but please make sure it will be call on MainThread, because AsyncTask has method doInBackground in background Thread. best practice is wrap fragment reference by WeakReference
public class AddIteamActivity extends AppCompatActivity {
ViewPager pager;
TabLayout tab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_iteam);
pager = findViewById(R.id.pager);
tab = findViewById(R.id.tab);
AddIteamsAdapter viewPagerAdapter = new AddIteamsAdapter(getSupportFragmentManager());
pager.setAdapter(viewPagerAdapter);
tab.setupWithViewPager(pager);
}
}

Progress Dialog in Twitter Async Task - Android

I want to bring up a progress dialog when the user loads up the twitter feed and when the twitter feed has loaded the progress dialog disappears.
This is the TwitterAsyncTask class:
public class TwitterAsyncTask extends AsyncTask<Object, Void, ArrayList<TwitterTweet>> {
ListActivity callerActivity;
private ProgressDialog pd;
final static String TWITTER_API_KEY = "ddd";
final static String TWITTER_API_SECRET ="fffff";
Context cnt;
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(cnt.getApplicationContext());
pd.setMessage("loading");
pd.show();
}
#Override
protected ArrayList<TwitterTweet> doInBackground(Object... params) {
ArrayList<TwitterTweet> twitterTweets = null;
callerActivity = (ListActivity) params[1];
if (params.length > 0) {
TwitterAPI twitterAPI = new TwitterAPI(TWITTER_API_KEY,TWITTER_API_SECRET);
twitterTweets = twitterAPI.getTwitterTweets(params[0].toString());
}
return twitterTweets;
}
#Override
protected void onPostExecute(ArrayList<TwitterTweet> twitterTweets) {
ArrayAdapter<TwitterTweet> adapter =
new ArrayAdapter<TwitterTweet>(callerActivity, R.layout.twitter_tweets_list,
R.id.listTextView, twitterTweets);
callerActivity.setListAdapter(adapter);
ListView lv = callerActivity.getListView();
lv.setDividerHeight(0);
lv.setBackgroundColor(callerActivity.getResources().getColor(R.color.white));
if (pd != null)
{
pd.dismiss();
}
}
}
And here is the class that calls the TwitterAsyncTask class:
public class MainActivity extends ListActivity {
final static String twitterScreenName = "CFABUK";
final static String TAG = "MainActivity";
private AsyncTask<Object, Void, ArrayList<TwitterTweet>> tat;
boolean done;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
done = false;
AndroidNetworkUtility androidNetworkUtility = new AndroidNetworkUtility();
if (androidNetworkUtility.isConnected(this)) {
new TwitterAsyncTask().execute(twitterScreenName, this);
} else {
Log.v(TAG, "Network not Available!");
}
}
public void timerDelayRemoveDialog(long time, final ProgressDialog d) {
new Handler().postDelayed(new Runnable() {
public void run() {
d.dismiss();
}
}, time);
}
}
the error seems to appear for the line pd = new ProgressDialog(cnt.getApplicationContext());...What should I put for this? thanks
Just add Constructor in your AsyncTask like
Context mContext;
public TwitterAsyncTask(Context mContext){
this.mContext=mContext;
}
And from your activity
Context mContext=this;
new TwitterAsyncTask(mContext).execute(twitterScreenName, this);
Instead of cnt.getApplicationContext() replace it with YourClassName.this
Embed your Async task in your activity, and replace your Context cnt by YourActivity.class... And please include some log.

Progess Dialog with fragment inside activity call asynctask

I have a main activity, which has a fragment inside, that calls an Asynctask.
Main Activity - The main activity has a ViewPager that loads the fragment.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.viewPager = (ViewPager)findViewById(R.id.pager);
this.mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
//actionBar.setSelectedNavigationItem(position);
//Toast.makeText(getApplicationContext(), "this is my Toast message!!! =)",
//Toast.LENGTH_LONG).show();
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
Fragment - Makes Call to service
public class SomeFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.article_view, container, false);
ServiceHelper srv = new ServiceHelper(getActivity(), "GetHomeImage", postParameters, 2);
AsyncTask<String, Void, String> request = srv.execute();
return view;
}
}
Async Task Class - Show Progressdialog and make requests
public class ServiceHelper extends AsyncTask<String, Void, String> {
public ServiceHelper(Context c, String method, HashMap<String, Object> parameters, int requestType){
context = c;
this.method = method;
this.parameters = parameters;
this.requestType = requestType;
}
protected void onPreExecute(){
progressDialog = ProgressDialog.show(context, "Requisição", "Chamando Serviço", true, false);
}
protected String doInBackground(String... params) {
do stuff...
}
protected void onPostExecute(String result) {
progressDialog.dismiss();
}
}
The problem I'm facing is that the fragment is called, the request is made, but the Progessdialog only appears when the fragment is shown.
It's possible to show the Progressdialog when the call is made?
Thanks.
I think the simple way here is show progress dialog before call to execute AsyncTask. for closing progress dialog you should add a Listener to ServiceHelper and listen it to dismiss dialog on cancel or completion of task. here is code:
final Dialog progressDialog = ProgressDialog.show(context, "Requisição", "Chamando Serviço", true, false);
ServiceHelper srv = new ServiceHelper(getActivity(), "GetHomeImage", postParameters, 2);
srv.setListener(new ServiceHelperListener() {
public void onCancel() {
progressDialog.dismiss();
}
public void onCompelte() {
progressDialog.dismiss();
}
});
AsyncTask<String, Void, String> request = srv.execute();
and ServiceHelper class and Listener:
public class ServiceHelper extends AsyncTask<String, Void, String> {
private ServiceHelperListener mListener;
public ServiceHelper(Context c, String method, HashMap<String, Object> parameters, int requestType){
context = c;
this.method = method;
this.parameters = parameters;
this.requestType = requestType;
}
public void setListener(ServiceHelperListener listener) {
this.mListener = listener;
}
protected void onPreExecute(){
}
protected String doInBackground(String... params) {
do stuff...
}
protected void onPostExecute(String result) {
if (mListener != null) {
mListener.onCompelte();
}
}
#Override
protected void onCancelled(String s) {
super.onCancelled(s);
if (mListener != null) {
mListener.onCancel();
}
}
}
public interface ServiceHelperListener {
public void onCancel();
public void onCompelte();
}

AsynkTask within Fragment within a ViewPager

First of all, I am relatively new to android programming.
I am creating a ViewPager application with two Fragments. One of the Fragments requests data from a server and return a result to the main FragmentActivity. My problem is that this request to the server can take sometime, and I have been trying to get a ProgressDialog to appear with AsyncTask while the user waits for the data to be retrieved. Once I create the background thread to retrieve the data, I successfully execute some code in the onPostExecute() method and set some variables. However, the return statement that sends information back to the FragmentActivity is being executed before the background thread actually ends. I can't seem to figure out a way for the main thread to wait on the background thread. Using Asyctask's get() method results in the ProgressDialog from appearing. I have looked through a lot of posts in here, but can't seem to find an answer.
Anything helps.
Code below:
SplashScreen.java
public class SplashScreen extends FragmentActivity {
MainMenu mainMenu;
MapScreen mapScreen;
PagerAdapter pagerAdapter;
ViewPager viewPager;
List<LatLng> geoPoints;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash_screen);
context = this;
initializePaging();
}
private void initializePaging()
{
mainMenu = new MainMenu();
mapScreen = new MapScreen();
pagerAdapter = new PagerAdapter(getSupportFragmentManager());
pagerAdapter.addFragment(mainMenu);
pagerAdapter.addFragment(mapScreen);
viewPager = (ViewPager) super.findViewById(R.id.viewPager);
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(2);
viewPager.setCurrentItem(0);
viewPager.setOnPageChangeListener(new OnPageChangeListener()
{
#Override
public void onPageScrollStateChanged(int postion){}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2){}
#Override
public void onPageSelected(int position)
{
switch(position){
case 0: findViewById(R.id.first_tab).setVisibility(View.VISIBLE);
findViewById(R.id.second_tab).setVisibility(View.INVISIBLE);
break;
case 1: findViewById(R.id.first_tab).setVisibility(View.INVISIBLE);
findViewById(R.id.second_tab).setVisibility(View.VISIBLE);
break;
}
}
});
}
//Called from onClick in main_mainu.xml
public void getDirections(View view)
{
InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
try
{
geoPoints = mainMenu.getDirections(context);
mapScreen.plotPoints(geoPoints);
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), "Error! Invalid address entered.", Toast.LENGTH_LONG).show();
mainMenu.clear();
}
}
}
MainMenu.java
public class MainMenu extends Fragment {
String testString;
int testInt;
TextView testTV;
private TextView tvDisplay;
private EditText departure;
private EditText destination;
private Geocoder geocoder;
private List<Address> departAddress;
private List<Address> destinationAddress;
private List<LatLng> geoPoints;
private String departString;
private String destinationString;
private Address departLocation;
private Address destinationLocation;
private LatLng departurePoint;
private LatLng destinationPoint;
private Context contextMain;
private GetData task;
public MainMenu()
{
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View root = (View) inflater.inflate(R.layout.main_menu, null);
geoPoints = new ArrayList<LatLng>(2);
return root;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
departure = (EditText) getView().findViewById(R.id.depart_field);
destination = (EditText) getView().findViewById(R.id.destination_field);
tvDisplay = (TextView) getView().findViewById(R.id.textView1);
}
public List<LatLng> getDirections(Context context)
{
contextMain = context;
geocoder = new Geocoder(getActivity());
departString = departure.getText().toString();
destinationString = destination.getText().toString();
try
{
task = new GetData(new Callback(){
public void run(Object result)
{
//return geoPoints;
}
});
task.execute((Void[])null);
}catch(Exception e)
{
e.printStackTrace();
}
return geoPoints;
}
public void clear()
{
departure.setText("");
destination.setText("");
tvDisplay.setText("Enter departure point, and destination point");
}
private class GetData extends AsyncTask<Void, Void, List<List<Address>>>
{
Callback callback;
private ProgressDialog processing;
public GetData(Callback callback)
{
this.callback = callback;
}
#Override
protected void onPreExecute()
{
processing = new ProgressDialog(contextMain);
processing.setTitle("Processing...");
processing.setMessage("Please wait.");
processing.setCancelable(false);
processing.setIndeterminate(true);
processing.show();
}
#Override
protected List<List<Address>> doInBackground(Void...arg0)
{
List<List<Address>> list = new ArrayList<List<Address>>(2);
try
{
departAddress = geocoder.getFromLocationName(departString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
destinationAddress = geocoder.getFromLocationName(destinationString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
list.add(departAddress);
list.add(destinationAddress);
}catch(IOException e)
{
e.printStackTrace();
}
return list;
}
#Override
protected void onPostExecute(List<List<Address>> list)
{
departLocation = list.get(0).get(0);
destinationLocation = list.get(1).get(0);
departurePoint = new LatLng(departLocation.getLatitude(), departLocation.getLongitude());
destinationPoint = new LatLng(destinationLocation.getLatitude(), destinationLocation.getLongitude());
if(geoPoints.size() >= 2)
{
geoPoints.clear();
}
geoPoints.add(departurePoint);
geoPoints.add(destinationPoint);
callback.run(list);
processing.dismiss();
}
}
}
#Override
protected Object doInBackground(Void...arg0)
{
Object result = null;
try
{
departAddress = geocoder.getFromLocationName(departString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
destinationAddress = geocoder.getFromLocationName(destinationString, 5, 37.357059, -123.035889, 38.414862, -121.723022);
}catch(IOException e)
{
e.printStackTrace();
}
return result;
}
You never set the value of result...

Android AsyncTask Better way of accessing Activity Context

It took my quite a while to get this to work, but It's clearly not best practice. In short, I need to show a dialog when my AsyncTask finishes, but getApplicationContext() does not work, neither does passing it as a parameter when creating the AsyncTask. So I've declared a public variable for the context in my AsyncTask class and set it before I execute:
private OnClickListener clickLoadRefs = new OnClickListener() {
#Override
public void onClick(View v) {
Log.d("H","Clicked Load Refs");
RefreshRefPoints refreshRefPoints = new RefreshRefPoints();
refreshRefPoints.myCtx=v.getContext();
refreshRefPoints.execute(v.getContext());
}
};
private class RefreshRefPoints extends AsyncTask<Context, Integer, Integer> {
private Integer nPoints=0;
public Context myCtx;
private ProgressDialog pd;
protected Integer doInBackground(Context... ctx) {
Log.d("H","doInBackground()");
dbHelper.clearRefPoints();
requestRefPoints();
nPoints = parseRefPointsCSV();
return nPoints;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPreExecute()
{
pd = ProgressDialog.show(myCtx, "Refreshing Reference Points", "Loading...", true,false);
Log.d( "H", "onPreExecute()" );
}
protected void onPostExecute(Integer result) {
pd.dismiss();
AlertDialog.Builder builder = new AlertDialog.Builder(myCtx);
builder.setTitle("Reference points refresh complete");
builder.setMessage(result+" records loaded");
builder.setPositiveButton("OK",null);
builder.show();
Log.d("H","onPostExecute()");
}...etc
Can anybody just show me the proper way of passing the context?
Thanks
Define a constructor method and pass context a parameter. It would be better.
Here what I meant:
private class RefreshRefPoints extends AsyncTask<Void, Integer, Integer> {
private Integer nPoints=0;
private Context myCtx;
private ProgressDialog pd;
public RefreshRefPoints(Context ctx){
// Now set context
this.myCtx = ctx;
}
}
That's all.
You may also use YourActivityName.this to refer to the activity Context. Because Activites extend Context, so its valid to do so.
Pass context in constructor as
private OnClickListener clickLoadRefs = new OnClickListener() {
#Override
public void onClick(View v) {
Log.d("H","Clicked Load Refs");
RefreshRefPoints refreshRefPoints = new RefreshRefPoints(Your_ActivityName.this);
refreshRefPoints.myCtx=v.getContext();
refreshRefPoints.execute(v.getContext());
}
};
private class RefreshRefPoints extends AsyncTask<Void, Integer, Integer> {
private Integer nPoints=0;
public Context myCtx;
private ProgressDialog pd;
public RefreshRefPoints (Context ctx) {
myCtx = ctx;
}

Categories

Resources