I have a splash screen that loads URLs from the Internal Storage and downloads their content from the Web (with an AsynkTask). It puts the downloaded data into an ArrayList, calls the main Activity and finishes. The main activity adapter manages the ArrayList and sets a ListView containing its data.
While I'm in the main Activity, if I press the back button the application exits (I set the android:nohistory="true" for the splash screen activity), but when I return to the app, the splash screen gets loaded and downloads the data again, "doubling" the list view.
How can I prevent the splash screen to be loaded when I return to the app?
Splash screen code:
Context mContext;
ProgressBar progress = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_launcher);
progress = (ProgressBar)findViewById(R.id.progress);
progress.setIndeterminate(true);
if(canWriteOnExternalStorage()) {
try {
setupStorage();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
//dialog appears
}
AsynkTask code:
private class LoadGames extends
AsyncTask<String, Integer, Boolean> {
private ProgressDialog mProgressDialog = null;
private String remoteUrl = null;
#Override
protected void onCancelled() {
Log.e(com.example.ludos2_0.MainActivity.TAG,
"AsyncTask->LoadGames: onCancelled !");
super.onCancelled();
}
#Override
protected void onPreExecute() {
Log.d(com.example.ludos2_0.MainActivity.TAG,
"AsyncTask->LoadGames: onPreExecute !");
}
#Override
protected Boolean doInBackground(String... params) {
if (params.length == 0)
return false;
else
for (int k = 0; k < (params.length)/2; ++k)
{
this.remoteUrl = params[k*2];
Log.d(com.example.ludos2_0.MainActivity.TAG,
"AsyncTask->LoadGames: doInBackground ! ("
+ this.remoteUrl + ")");
// HTTP Request to retrieve the videogames list in JSON format
try {
// Creates the remote request
Log.d(com.example.ludos2_0.MainActivity.TAG,
this.remoteUrl);
RESTRequest request = new RESTRequest(this.remoteUrl);
request.isMethodGET(true);
// Executes the request and print the received response
String response = RESTRequestExecutor.execute(request);
// Custom/Manual parsing using GSON
JsonParser parser = new JsonParser();
if (response != null && response.length() > 0) {
Log.d(com.example.ludos2_0.MainActivity.TAG, "Response: "
+ response);
JsonObject jsonObject = (JsonObject) parser.parse(response);
JsonObject itemObj = jsonObject.getAsJsonObject("results");
String id = null;
String title = null;
String thumbnail = null;
String description = null;
String image = null;
String platform = null;
id = itemObj.get("id").getAsString();
title = itemObj.get("name").getAsString();
if (!(itemObj.get("image").isJsonNull()))
{
thumbnail = ((JsonObject)itemObj.get("image")).get("tiny_url").getAsString();
image = ((JsonObject)itemObj.get("image")).get("small_url").getAsString();
}
else
{
thumbnail = "http://www.persicetometeo.com/images/not_available.jpg";
image = "http://www.persicetometeo.com/images/not_available.jpg";
}
description = itemObj.get("deck").getAsString();
platform = params[k*2 + 1];
Log.d(com.example.ludos2_0.MainActivity.TAG,
title);
ListsManager.getInstance().addVideogame(new Videogame(id, title, thumbnail, image, description, platform));
} else {
Log.d(com.example.ludos2_0.MainActivity.TAG,
"Error getting response ...");
}
} catch (Exception e) {
e.printStackTrace();
Log.e(com.example.ludos2_0.MainActivity.TAG,
"Exception: " + e.getLocalizedMessage());
}
}
return true;
}
#Override
protected void onPostExecute(Boolean result) {
Log.d(com.example.ludos2_0.MainActivity.TAG,
"AsyncTask->LoadGames: onPostExecute !");
progress.setVisibility(View.GONE);
if (result == false) {
Log.e(com.example.ludos2_0.MainActivity.TAG,
"AsyncTask->LoadGames: Error Downloading Data !");
} else {
Log.d(com.example.ludos2_0.MainActivity.TAG,
"AsyncTask->LoadGames: Data Correctly Downloaded !");
Intent intent = new Intent(mContext, MainActivity.class);
startActivity(intent);
finish();
}
super.onPostExecute(result);
}
}
The setupStorage() method loads the file from the Storage and executes the AsynkTask.
Maybe could the overriding of the onRestart() method be a solution?
Or should I prevent the AsyncTask from loading the data already downloaded?
Thanks!
It would be better to prevent AsynkTask to download it again. Or better to clear your listview data. Means if use ArrayList with your List adapter then just clear it before storing putting new data.
Related
I am calling rest API which gets access token from salesforce. after I make a rest call to get data from Salesforce and I'm successfully getting records. and all records are shown in android activity list view.
after that I call fragment but fragment view is not showing.
if I'm not making rest call then fragment show properly.
Here is the MainActivity class
public class MainActivity extends AppCompatActivity {
DrawerLayout dLayout;
private ArrayAdapter<String> listAdapter;
ProgressDialog progressDialog;
JSONTokener tokener;
String accessToken_, instanceURL_;
JSONArray finalResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setNavigationDrawer(); // call method
// button_save_account = (Button) findViewById(R.id.button_save_account);
accessToken_ = "00D7F000005oJve!ARUAQPJ8hMWibtO1flIPjZfzV4A__Kzj6wTjJ5XA_xE1zbqDs_0fOTZuxJFiLVxsFx_kNPxuNNK6c7yREtbxq4J7W1oWuUEs";
instanceURL_ = "https://harishgakhar40-dev-ed.my.salesforce.com";
// Create list adapter
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>());
((ListView) findViewById(R.id.contacts_list)).setAdapter(listAdapter);
try {
MyAsyncTasks myAsyncTasks = new MyAsyncTasks();
myAsyncTasks.execute(accessToken_, instanceURL_).get();
} catch (Exception e) {
}
}
private void setNavigationDrawer() {
dLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // initiate a DrawerLayout
NavigationView navView = (NavigationView) findViewById(R.id.navigation); // initiate a Navigation View
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
Fragment frag = null; // create a Fragment Object
int itemId = menuItem.getItemId(); // get selected menu item's id
if (itemId == R.id.first) {
frag = new InsertRecords();
Bundle bundle = new Bundle();
bundle.putString("access token", accessToken_);
bundle.putString("instanc url", instanceURL_);
frag.setArguments(bundle);
} else if (itemId == R.id.second) {
Log.v("fragment second ---- ", "In Fragment Second ---- ");
frag = new SecondFragment();
} else if (itemId == R.id.third) {
frag = new ThirdFragment();
}
Toast.makeText(getApplicationContext(), menuItem.getTitle(), Toast.LENGTH_SHORT).show();
if (frag != null) {
Log.v("frag ---- ", "frag ------ " + frag);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Log.v("transaction ---- ", "transaction ------ " + frag);
transaction.replace(R.id.frame, frag); // replace a Fragment with Frame Layout
transaction.commit(); // commit the changes
dLayout.closeDrawers(); // close the all open Drawer Views
return true;
}
return false;
}
});
}
public class MyAsyncTasks extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// display a progress dialog for good user experiance
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Please Wait");
progressDialog.setCancelable(false);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
String accessToken = params[0];
String instanceURL = params[1];
// implement API in background and store the response in current variable
String result = "";
DefaultHttpClient client = new DefaultHttpClient();
String url = instanceURL + "/services/data/v20.0/query/?q=";
String soqlQuery = "Select Id, Name, BillingStreet, BillingCity, BillingState From Account Limit 10 ";
try {
url += URLEncoder.encode(soqlQuery, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
HttpGet getRequest = new HttpGet(url);
getRequest.addHeader("Authorization", "OAuth " + accessToken);
Log.v("Token in doin ---- ", "accessToken ---- in doin ---- " + accessToken);
Log.v("instanceURL doin ---- ", "instanceURL ---- in doin ---- " + instanceURL);
try {
HttpResponse response = client.execute(getRequest);
result = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String result) {
try {
progressDialog.dismiss();
// dismiss the progress dialog after receiving data from API
JSONObject object = (JSONObject) new JSONTokener(result).nextValue();
JSONArray records = object.getJSONArray("records");
// globalState.setAccountNames(new String[records.length()]);
// globalState.setAccounts(new JSONObject[records.length()]);
listAdapter.clear();
for (int i = 0; i < records.length(); i++) {
JSONObject record = (JSONObject) records.get(i);
String accountName = record.getString("Name");
Log.v("accountName---- ", "accountName ---- " + accountName);
listAdapter.add(accountName);
// globalState.getAccountNames()[i] = accountName;
//globalState.getAccounts()[i] = record;
}
} catch (Exception e) {
}
Log.d("data", result.toString());
}
}
}
You are blocking MainThread which is rendering UI.
To avoid this, android provides AsyncTask.
BUT make yourself and others working on your project favor and use Retrofit or other libraries. It will save you so much time and make your code cleaner.
Here you can find a good article.
If you really don't feel like using Retrofit, AsyncTask is an option too
You need to call your getAccountData function inside an AsyncTask. The implementation right now is blocking your UI thread, which created the problem I think.
public class GetAccountData implements AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
// Get account data here.
}
#Override
protected void onPostExecute(final String accountName) {
// Pass the accountName to the calling Activity here.
}
// Implement other methods if you need
}
If you are confused about how you can pass the data from your AsyncTask to your Activity, please consider looking into this answer here.
I have this function where it checks what are the choices of the users made.
So for example
there is a 4 choices:
InfoOfUp
InfoOfArt
InfoOfParish
InfoOfAteneo.
So when the user selects InfoOfUp and InfoOfArt then on the next activity, i will click a button that contains function : selected() it will check the items that was choosen by the user. if the user choose item InfoOfUp it will run a specific function and if the user choose item InfoOfArt it will also run a specific function
The problem is every item has it's own function and every item have progress dialog that marks if the function is already done or not.
So the user choose 2 items there's an error because there's 2 function being called up at the same time;
I want the function to be call 1by1 where the function waits to the other function to finish.
To avoid confusion, i call methods as function.
public void selected() {
if (InfoOfUp.select == 1) {
if (ayala == 0) {
ayala();
ayala = 1;
} else if (ayala == 1) {
}
}
if (InfoOfArt.select == 1) {
if (art == 0) {
ArtInIsland();
art = 1;
} else if (art == 1) {
}
}
if (InfoOfParish.select == 1) {
if (parish == 0) {
parish();
parish = 1;
} else if (parish == 1) {
}
}
if (InfoOfAteneo.select == 1) {
if (ateneo == 0) {
ateneogallery();
ateneo = 1;
} else if (ateneo == 1) {
}
}
Additionally, if the function calls, it will run an asynctask to get data.
here is my asynctask:
public class connectAsyncTask3 extends AsyncTask<Void, Void, String> {
private ProgressDialog progressDialog;
private traffic traffic;
private boolean displayDestinationDetails;
String url;
boolean launchDestination;
connectAsyncTask3(String urlPass, traffic traffic, boolean displayDestinationDetails) {
this.url = urlPass;
this.traffic = traffic;
this.displayDestinationDetails = displayDestinationDetails;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
try {
super.onPreExecute();
progressDialog = new ProgressDialog(traffic.this);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected String doInBackground(Void... params) {
JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);
return json;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.hide();
if (result != null) {
Log.d("momo2", " : " + result);
traffic.drawPath(result);
speakOut();
}
if (displayDestinationDetails) {
Intent i = new Intent(traffic.this, poppers.class);
i.putExtra("currentMarker", traffic.markers.size());
traffic.startActivity(i);
}
}
}
Classic multi threading situation.
Create two threads, each one in the method related, start them and use
thread.join()
to begin second thread only after first finished.
great example here
I have an activity that calls JSON data from a foreign database.
Below is my ideal case for my app:
The JSON data is parsed and inserted into an SQLite database on Android
Next activity is started and the newly inserted data is read from the SQLite database
What actually happens:
The JSON data is parsed and inserted into an SQLite database on Android
The next activity is started while data is still being inserted and returns zero when reading from the desired databse for my ListArray in that activity.
How do I force Android to wait until database insertion is completed before starting the next activity?
EDIT
My doInBackground looks as follows:
#Override
protected String doInBackground(String... params) {
StringRequest strReq = new StringRequest(Request.Method.GET,
str, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
JSONArray jObjInside = jObj.getJSONArray("service_prov_services");
for (int i = 0; i < jObjInside.length(); i++) {
// Now store the user in SQLite
try {
// JSONObject user = jObj.getJSONObject("user");
String service_prov_type = jObj.getString("service_prov_type");
String service_prov_name = jObj.getString("service_prov_name");
String addr_street = jObj.getString("addr_street");
String addr_num = jObj.getString("addr_number");
String addr_plz = jObj.getString("addr_plz");
String addr_city = jObj.getString("addr_city");
JSONObject elem = jObjInside.getJSONObject(i);
if(elem != null){
String service_id = elem.getString("service_id");
String service_type = elem.getString("service_type");
String service_measure = elem.getString("service_measure");
// Inserting row in userServiceProvServices table
db.addUserServiceProvServices(service_id, service_prov_type,
service_prov_name, addr_street, addr_num, addr_plz, addr_city, service_type, service_measure);
Log.d("post_url for service", addr_plz );
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getActivity().getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
Log.d("test string to appcntr",strReq.toString());
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
return params[0];
}
onPostExecute looks as follows:
#Override
protected void onPostExecute(String Result) {
//super.onPostExecute(Result);
pdLoading.dismiss();
//this method will be running on UI thread
Log.d(TAG, "Stamp: " + Result);
Bundle args = new Bundle();
args.putString("stampID", Result);
ProviderServiceListFragment frag = new ProviderServiceListFragment();
frag.setArguments(args);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame,
frag)
.commit();
}
With the way I am doing it now, my next Fragment is already called, although the data has not finished being entered into the database. This means the ListArray in the follwoing Fragment is empty because of the missing database data.
I worked on this for a month and finally figured it out for myself (stupid nube I am..) So here is a piece of code inserting a record to sqlite.
On the chosen event ("onClick actionbutton1") a new AsyncTask is created with doInBackground, onPreExecute and onPostExecute.
onPreExecute will setMessage() and show() the progressDialog which will start spinning
onPostExecute will handle the new/next Activity
READ BELOW FOR doInBackground!!
actionButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ProgressDialog progressDialog = new ProgressDialog(AddUpdateEvf.this);
new AsyncTask<Void, Void, Boolean>() {
protected Boolean doInBackground(Void... params) {
doOneThing();
return null;
}
#Override
protected void onPreExecute() {
progressDialog.setMessage("Processing...");
progressDialog.show();
}
protected void onPostExecute(Boolean result) {
evaluationFormOps.close();
progressDialog.dismiss();
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(AddUpdateEvf.this);
alertDialogBuilder.setMessage("Added to Database...")
.setCancelable(false)
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
i = new Intent(AddUpdateEvf.this, ViewProduct.class);
i.putExtra(EXTRA_ADD_UPDATE, "View");
i.putExtra(EXTRA_PRODUCT_ID, hiddenTextId.getText().toString());
i.putExtra(EXTRA_PRODUCT_NO, productNo_tv.toString());
startActivity(i);
dialog.dismiss();
finish();
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
private void doOneThing() {
makeDbRequest();
do {
evfId = newEvf.getEvfId();
}
while (evfId<1);
}
}.execute();
}
});
Note this snippet in the above code called in doInBackground():
private void doOneThing() {
makeDbRequest();
do {
evfId = newEvf.getEvfId();
}
while (evfId<1);
}
Note: The makeDbRequest() handles the insert to sqlite by setting the values and then passing it to another class which handles the cursor and puts the values etc.
Heres a small snippet of relevant code in that class (which you should already have mastered...):
public Evf addEvf(Evf evf, String dBsuccess){
ContentValues values = new ContentValues();
values.put(TableHelper.PRODUCT_IDE,evf.getPRODUCTId());
values.put(TableHelper.CSCORE,evf.getcScore());
values.put(TableHelper.FSCORE,evf.getfScore());
values.put(TableHelper.TSCORE,evf.gettScore());
values.put(TableHelper.WEIGHT,evf.getWeight());
values.put(TableHelper.TEMP,evf.getTemp());
values.put(TableHelper.STATUS,evf.getStatus());
values.put(TableHelper.TIMESTAMP, String.valueOf(evf.getTimeStamp()));
values.put(TableHelper.LOADED, dBsuccess);
long insertid = database.insert(TableHelper.TABLE_EVFS,null,values);
evf.setEvfId((int) insertid);
return evf;
}
So above you can see the Id of, in my case evaluationform(Evf), being set to the insert id. This happens after the insert and you can set any value in your object class (the one with getters and setters...Evf())
Finally, use the do...while statement above to "listen" for the value being set in the object class
This can obviously only happen if the insert was finished and the onPosteExecute takes care of the rest
Hope it helps, crit is welcome, PEACHES!!
Use AsyncTask to process the Database insertion process & then use the onPostExecute method to move away from the current activity.
private class ProcessDatabase extends AsyncTask<String, String, String> {
String sampleData;
#Override
protected String doInBackground(String... params) {
//Call your Database Insert method here.
//In this example, I am inserting sampleData to the DB
return null;
}
#Override
protected void onPostExecute(String result) {
//This gets triggered when the process is complete
}
}
You can start the AsyncTask by adding the following code in your onCreate or where ever you want to start the DB Insertion process:
//in this case I am just passing a string, You can create your own
//custom class & send that as well
ProcessDatabase.execute(myData);
Refer this link for more information. Good luck!
The StringRequest is an Asynchronous request, so upon the executing the those lines onPostExecute will called immediately, so there is no guarantee that the sql update will complete before the next activity is launched.
Call the nextActivity at the end of the onResponse callback method of the StringRequest which way you can guarantee to insert the data to db first and then call the nextActivity.
private void makeJsonRequest(String str) {
StringRequest strReq = new StringRequest(Request.Method.GET,
str, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
JSONArray jObjInside = jObj.getJSONArray("service_prov_services");
for (int i = 0; i < jObjInside.length(); i++) {
// Now store the user in SQLite
try {
// JSONObject user = jObj.getJSONObject("user");
String service_prov_type = jObj.getString("service_prov_type");
String service_prov_name = jObj.getString("service_prov_name");
String addr_street = jObj.getString("addr_street");
String addr_num = jObj.getString("addr_number");
String addr_plz = jObj.getString("addr_plz");
String addr_city = jObj.getString("addr_city");
JSONObject elem = jObjInside.getJSONObject(i);
if (elem != null) {
String service_id = elem.getString("service_id");
String service_type = elem.getString("service_type");
String service_measure = elem.getString("service_measure");
// Inserting row in userServiceProvServices table
db.addUserServiceProvServices(service_id, service_prov_type,
service_prov_name, addr_street, addr_num, addr_plz, addr_city, service_type, service_measure);
Log.d("post_url for service", addr_plz);
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
goNextActivity();
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getActivity().getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
Log.d("test string to appcntr", strReq.toString());
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void goNextActivity(){
//this method will be running on UI thread
ProviderServiceListFragment frag = new ProviderServiceListFragment();
frag.setArguments(args);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame,
frag)
.commit();
}
An Activity (SignInActivity) is calling a method in FunkcjeAPI which execute an AsyncTask.
My AsyncTask should show a ProgressDialog using an calling Activity. I don't know how to give it an correct Activity to the constructor. I tried a lot of thing, read a lot of tutorials and questions on SO, but I can't find solution. FunkcjeAPI isn't an Activity so I can't write new Logowanie(this).execute(argumenty);
AsyncTask calling code :
public class FunkcjeAPI {
static String dozwrotu = null;
public static String zalogujSie(final String nick, final String haslo)
{
String[] argumenty = {nick, haslo};
new Logowanie(/* WHAT HERE ? */).execute(argumenty); // HELP ME IN THAT LINE !!!!!!!!!!!!!
return dozwrotu;
}
My AsyncTask class code (it is in FunkcjeAPI class):
private class Logowanie extends AsyncTask<String, Void, String>
{
Activity wywolujaceActivity;
public Logowanie(Activity wywolujaceActivity) {
this.wywolujaceActivity = wywolujaceActivity;
}
#SuppressWarnings("deprecation")
#Override
protected void onPreExecute() {
wywolujaceActivity.showDialog(SignInActivit.PLEASE_WAIT_DIALOG);
}
#Override
protected String doInBackground(final String... argi) {
final JSONParser jParser = new JSONParser();
new Thread(new Runnable() {
public void run() {
final String json = jParser.getJSONFromUrl("http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + argi[0] + "&password=" + argi[1] + "&imei=");
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
#Override
public void run() {
JSONObject jObject;
try {
jObject = new JSONObject(json);
Log.wtf("Link", "http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + argi[0] + "&password=" + argi[1] + "&imei=");
Log.wtf("Link", json);
String error = jObject.getString("error");
if(error == "You reached daily query limit !") { nadajWartosc("You reached daily query limit !"); }
if(error == "0") {nadajWartosc(jObject.getString("token"));}
if(error == "1") {nadajWartosc("1");}
if(error == "Invalid username") {nadajWartosc("Invalid username");}
if(error == "Invalid password") {nadajWartosc("Invalid password");}
if(error == "This user is already logged in !") {nadajWartosc("This user is already logged in !");}
} catch (JSONException e1) {
e1.printStackTrace();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
});
}}).start();
return dozwrotu;
}
#Override
protected void onPostExecute(String result) {
wywolujaceActivity.removeDialog(SignInActivit.PLEASE_WAIT_DIALOG);
}
}
Add one more parameter to zalogujSie() method that takes an Activity, and then use this parameter to start the AsyncTask:
public static String zalogujSie(Activity activity, final String nick, final String haslo)
{
// .....
new Logowanie(activity).execute(argumenty);
return dozwrotu;
}
Then you would call this method from the activity like this:
FunkcjeAPI.zalogujSie(this, "Nick", "Haslo");
I have wrote an app to run an AsyncTask and part of the code is listed as follow. The problem is when the AsyncTask start by execute the code - "new AddImageTask().execute();" in the thread handler, the task will start and everything seems right. However, eventually the app will stay in "doInBackground" method after all code in "doInBackground" method has been executed. The task can't go to "onPostExecute" method. (i.e. can't dismiss the dialog...) What get wrong?
Thanks for the help......
private Handler handleFetchResult = new Handler() {
#Override
public void handleMessage(Message msg) {
progressDialog.dismiss();
Log.d(TAG, "Start handle fetch result");
try {
JSONArray ja = new JSONArray(fetchResult);
Log.d(TAG, "JSON Array Length = " + ja.length());
JSONObject jo = new JSONObject();
for (int i = 0; i < ja.length(); i++) {
jo = ja.getJSONObject(i);
PhotoURLs.add(PAT_url + jo.getString("filePath"));
Log.d(TAG, PhotoURLs.get(i));
}
} catch (JSONException e) {
Log.d(TAG, "Fetch result error: " + e.getLocalizedMessage());
e.printStackTrace();
}
//TODO: display thumbnail
new AddImageTask().execute();
}//void handleMessage
};//Handler handleFetchResult
class AddImageTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
loadThumbnailDialog.show(SitePhotoGallery.this, "Fetch thumbnails from server",
"Loading...", true, true);
Log.d("AddImageTask.onPreExecute","onPreExecute");
}
#Override
protected Void doInBackground(Void... unused) {
// TODO Auto-generated method stub
for (String url : PhotoURLs) {
String filename = url.substring(url.lastIndexOf("/") + 1, url.length());
String thumburl = url.substring(0, url.lastIndexOf("/")+1);
imgAdapter.addItem(LoadThumbnailFromURL(thumburl + filename));
publishProgress();
}
Log.d("AddImageTask.doInBackground","doInBackground");
return null ;
}
#Override
protected void onProgressUpdate(Void... unused) {
super.onProgressUpdate();
imgAdapter.notifyDataSetChanged();
Log.d("AddImageTask.onProgressUpdate","OnProgressUpdate");
}
protected void onPostExecute(Void... unused) {
super.onPostExecute(null);
loadThumbnailDialog.dismiss();
Log.d("AddImageTask.onPostExecute","onPostExecute");
}
}
I think it's because onPostExecute() should take a Void parameter and not a Void... parameter. (You should also specify #Override as Soxxeh pointed out in his/her comment above.)