I've got a AsyncTask that will not finish when I have my lib.roomAvailable() call in the doInBackground method. When QueueTask is called a progressDialog will show and
it sticks. It should go away after 5 seconds.
If I remove lib.roomAvailable() from the doInBackground method everything work as expected. Why do I get this strange behaviour when I call lib.roomAvailable()?
roomAvailable() calls another AsyncTask can this be an issue?
public class QueueTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
private Library lib;
private String date;
private int room;
private int time;
private String user;
private String id;
public QueueTask(String date, int room, int time, String user, String id) {
this.date = date;
this.room = room;
this.time = time;
this.user = user;
this.id = id;
}
#Override
protected void onPreExecute() {
lib = new Library();
progressDialog = ProgressDialog.show(ManageRoomActivity.this, "Queuing", "Queuing process", true);
}
#Override
protected Void doInBackground(Void... params) {
int timer = 5;
while(timer > 0) {
if(lib.roomAvailable(date, room, time)) {
Log.w("RoomAvailable", "Room Available");
}
android.os.SystemClock.sleep(1000);
timer --;
Log.w("TIMER", "" + timer);
}
progressDialog.dismiss();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
progressDialog.dismiss();
Intent intent = new Intent(ManageRoomActivity.this, DatePickerActivity.class);
ManageRoomActivity.this.startActivity(intent);
}
}
EDIT 1:
public boolean roomAvailable(String date, int room, int time) {
boolean available = false;
String timeString = "";
if(time < 10)
timeString = "0";
timeString = timeString + time;
String roomNum = "";
if(room < 10)
roomNum = "0";
roomNum = roomNum + room;
AsyncTask<String, Void, String> readSource = new URL_Source();
String source = "";
try {
String uri = getURI(date);
source = readSource.execute(getURI(date)).get();
String[] chunks = source.split("<td");
for(String chunk:chunks) {
if(chunk.contains(date) & chunk.contains("=Grp" + roomNum) & chunk.contains("stid=" + timeString))
available = true;
}
return available;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return available;
}
The other AsyncTask:
public final class URL_Source extends AsyncTask<String, Void, String> {
public URL_Source() {
}
protected String doInBackground(String... uri) {
try {
URL url = new URL(uri[0]);
InputStream in = url.openStream();
StringBuilder source = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while((line = reader.readLine()) != null) {
source.append(line);
}
in.close();
return source.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "ERROR";
}
}
Solution:
I didn't have a clue how AsyncTask worked. You cannot call a AsynchTask within a AsyncTask!
You are attempting to create and start an AsyncTask from a thread other than the UI thread. That is not supported:
http://developer.android.com/reference/android/os/AsyncTask.html
See the section entitled "Threading Rules"
Related
Hi guys I am trying to retrieve some movie information in JSON format but I cannot seem to work out what the problem of my code is. The data retrieving and processing itself all works but the problem is that when I pass my title input in the EditText and retrieve that data from another activity, I cannot seem to be able to utilize it. I passed the extra retrieved into the parameter of my data processing class ParseJsonData. However, I get a null pointer exception at where I set title.setText(parseJsonData.getMovie().getTitle()). The strange aspect of this is that if I just run ParseJsonData in the MainActivity by passing in the title myself, I am able to retrieve the title of the data, observed through log. Is there anything that I should be aware of when I am passing an extra as a parameter of a constructor?
public class ResultsPage extends AppCompatActivity {
private final String LOG_TAG = getClass().getSimpleName();
private TextView title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results_page);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTextViews();
}
private void setTextViews () {
Bundle bundle = getIntent().getExtras();
String movieTitle = bundle.getString("title");
Log.v(LOG_TAG, "title recieved is : " + movieTitle);
ParseJsonData parseJsonData = new ParseJsonData(movieTitle);
parseJsonData.execute();
title.setText(parseJsonData.getMovie().getTitle());
}
}
Below is ParseJsonData
public class ParseJsonData extends GetRawData{
private String mUrl;
private String title;
private static final String LOG_TAG = "ParseJsonData";
private Movie movie;
public ParseJsonData(String title) {
this.title = title;
processUrl();
}
#Override
public void execute() {
super.setUrl(mUrl);
ParseJsonDataBackground parseJsonDataBackground = new ParseJsonDataBackground();
parseJsonDataBackground.execute(mUrl);
}
public Movie getMovie() {
return movie;
}
private void processUrl () {
final String BASE_URL = "http://www.omdbapi.com/";
final String MOVIE_TITLE = "t";
final String MOVIE_YEAR = "y";
final String MOVIE_PLOT = "plot";
final String MOVIE_DATA_TYPE = "r";
mUrl = Uri.parse(BASE_URL).buildUpon().appendQueryParameter(MOVIE_TITLE, title).appendQueryParameter(MOVIE_YEAR, "").appendQueryParameter(MOVIE_PLOT, "short").appendQueryParameter(MOVIE_DATA_TYPE, "json").build().toString();
Log.v(LOG_TAG, "New Url address is : " + mUrl);
}
public class ParseJsonDataBackground extends GetRawDataBackground {
#Override
protected String doInBackground(String... params) {
return super.doInBackground(params);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
processData(getmData());
}
private void processData (String mData){
try {
final String MOVIE_TITLE = "Title";
JSONObject jsonObject = new JSONObject(mData);
Log.v(LOG_TAG, mData);
String title = jsonObject.getString(MOVIE_TITLE);
movie = new Movie(title);
Log.v(LOG_TAG, "Title of the movie is " + movie.getTitle());
}catch (JSONException e){
Log.e(LOG_TAG, "Error retrieving JsonData");
e.printStackTrace();
}
}
}
}
This is an extension of GetRawData which is below
public class GetRawData {
private String url;
private String mData;
private static final String LOG_TAG = "GetRawData";
public GetRawData() {
}
public String getmData() {
return mData;
}
public void setUrl(String url) {
this.url = url;
}
public void execute () {
GetRawDataBackground getRawDataBackground = new GetRawDataBackground();
getRawDataBackground.execute(url);
}
public class GetRawDataBackground extends AsyncTask<String, Void, String>{
private StringBuffer stringBuffer;
#Override
protected String doInBackground(String... params) {
mData = processDownloads (params[0]);
if (mData == null){
Log.e(LOG_TAG, "Null returned during processing");
return null;
}
return mData;
}
#Override
protected void onPostExecute(String s) {
Log.v(LOG_TAG, "Data retrieved is : " + s);
super.onPostExecute(s);
}
private String processDownloads (String mUrl){
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
if (mUrl == null){
return null;
}
URL url = new URL(mUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
Log.d(LOG_TAG, "Response code is : " + responseCode);
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
stringBuffer = new StringBuffer();
String line = new String();
while ((line = reader.readLine()) != null) {
stringBuffer.append(line);
}
return stringBuffer.toString();
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "MalformedURLException");
return null;
} catch (IOException e){
Log.e(LOG_TAG, "IOException in making connection");
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Log.e(LOG_TAG, "Error attempting to close reader");
}
}
}
}
}
}
It's because you're instantiating movie in the background task. It happens in a parallel thread (Thread 2). Your main thread calls getMovite().getTitle(); but movie is not set yet as Thread 2 is still running.
You should pass a callback to ParseJsonData from MainActivity and call the callback in onPostExecute. Make sure you return to the MainThread when you update the text view though.
public class ParseJsonDataBackground extends GetRawDataBackground {
public interface ParseJsonCallback{
void onJsonReady(Movie movie);
}
private ParseJsonCallback callback;
ParseJsonDataBackground(ParseJsonCallback callback){
this.callback = callback;
}
.....
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
processData(getmData());
callback.onJsonReady(movie);
}
.....
}
And in MainActivity
....
ParseJsonData parseJsonData = new ParseJsonData(movieTitle, new ParseJsonCallback(){
void onJsonReady(Movie movie){
runOnUiThread(new Runnable() {
#Override
public void run() {
title.setText(movie.getTitle());
}
});
}
});
parseJsonData.execute();
....
I am new to android and am completely puzzled by AsyncTasks. I need to create a leaderboard which will pull global leaderboard scores from a server.
I have posted below the two methods that were created in the LeaderboardsFragment which are used to access and display the scores - getGlobalScores and readStream.
I am unsure of how to use these in the AsyncTask - mostly how and what parameters to pass to the AsyncTask - most of the tutorials I have been looking at do not deal with 2D arrays. Any hints would be really appreciated, I am really having trouble understanding the literature surrounding this.
package uk.ni.appidemic.whackamole;
import java.io.BufferedReader;
public class LeaderboardsFragment extends Fragment {
AssetStore AS;
private TextView TopScores;
private String[][] global_scores = new String[10][3];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_leaderboards, container, false);
//Go and get the asset store from the activity
AS = WhackAMoleActivity.getAssetManager();
TopScores = (TextView) rootView.findViewById(R.id.leaderboards);
// Extract and display the top score text view from the preferences
displayLocalScores();
// this method is used to send a highscore to the server (name and score)
// this method may get pulled out to the gameloop as its the only place it should be used in the final game
// but this can be used for testing purposes atm (Server needs to be on)
// sendScoreGlobal("porter", 1001);
//async Get global scores from the server and display them - new thread
new AsyncOperation().execute();
...................
public void getGlobalScores() {
//gets global score in HTML format to be parsed
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
URL url = new URL("http://62........./high_scores");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
/gets the data and stores the global scores in a 2d array
//it then displays to screen
public void readStream(InputStream in) {
BufferedReader reader = null;
try {
StringBuilder htmlIn = new StringBuilder();
StringBuilder globalScoreBuilder = new StringBuilder();
htmlIn.append("");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
htmlIn.append(line);
}
// String to be scanned to find the pattern.
String html = htmlIn.toString();
String regexPattern = "<td align=\"left\" style=\"padding-left:10px;\">(\\d+?)</td>|<td align=\"right\" style=\"padding-right:10px;\">(\\w+?)</td>";
// Create a Pattern object
Pattern patternObject = Pattern.compile(regexPattern);
// Now create matcher object.
Matcher matcherObject = patternObject.matcher(html);
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Trying to find regex matches");
TopScores.append("\n");
int nextFreePointer = 0;
int rowCount = 0;
while (matcherObject.find()) {
if (matcherObject.group(1) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(1));
globalScoreBuilder.append(matcherObject.group(1) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(1);
nextFreePointer++;
}
if (matcherObject.group(2) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(2));
globalScoreBuilder.append(matcherObject.group(2) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(2);
nextFreePointer++;
}
if (nextFreePointer > 2) {
nextFreePointer = 0;
rowCount++;
}
globalScoreBuilder.append("\n");
}
StringBuilder sb = new StringBuilder();
String lineSeparator = System.getProperty("line.separator");
for (String[] row : global_scores) {
sb.append(Arrays.toString(row)).append(lineSeparator);
}
String text = sb.toString();
TopScores.append("Global Top 10 Scores\n");
TopScores.append(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class AsyncOperation extends AsyncTask<String, Void, Void>{
protected void onPreExecute(){
}//end of onPreExecute
#Override
protected Void doInBackground(Void... values) {
}//doinBackground
protected void onProgressUpdate(Void... values){
}//onProgressUpdate
protected void onPostExecute(Void... result){
}//end of onPostExecute
}//end of AsyncOperation inner class
}//end of Leaderboards class
You should fetch your game score through a WebService class that extentds AsynTask. Below is my class that I am using in order to fetch remote data safely.
CODE:
public class WebServiceRestTask extends AsyncTask<HttpUriRequest, Void, Object> {
private static final String TAG = "WebServiceRestTask";
private AbstractHttpClient mClient;
private WeakReference<WebServiceRestCallback> mCallback;
private int ws_task;
public WebServiceRestTask(int ws_task) {
this(new DefaultHttpClient(), ws_task);
}
public WebServiceRestTask(AbstractHttpClient client, int task_number) {
mClient = client;
this.ws_task = task_number;
}
public interface WebServiceRestCallback {
public void onRequestSuccess(String response);
public void onRequestError(Exception error);
}
public void setResponseCallback(WebServiceRestCallback callback) {
mCallback = new WeakReference<WebServiceRestCallback>(callback);
}
#Override
protected Object doInBackground(HttpUriRequest... params) {
try {
HttpUriRequest request = params[0];
HttpResponse serverResponse = mClient.execute(request);
BasicResponseHandler handler = new BasicResponseHandler();
String response = handler.handleResponse(serverResponse);
return response + ws_task;
} catch (Exception e) {
Log.w(TAG, e);
return e;
}
}
#Override
protected void onPostExecute(Object result) {
if (mCallback != null && mCallback.get() != null) {
if (result instanceof String) {
mCallback.get().onRequestSuccess((String) result);
} else if (result instanceof Exception) {
mCallback.get().onRequestError((Exception) result);
} else {
mCallback.get().onRequestError(
new IOException("Unknown Error Contacting Host"));
}
}
}
}
Not at my workstation but think something like this should work.
public class AsyncOperation extends AsyncTask<String, Void, Void>{
private String[][] global_scores = new String[10][3];
protected void onPreExecute(){
// optionally show loading indicator
TopScores.append("\n");
}//end of onPreExecute
#Override
protected Void doInBackground(Void... values) {
try {
URL url = new URL("http://62........./high_scores");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}//doinBackground
protected void onProgressUpdate(Void... values){
}//onProgressUpdate
protected void onPostExecute(Void... result){
// optionally hide loading indicator
StringBuilder sb = new StringBuilder();
String lineSeparator = System.getProperty("line.separator");
for (String[] row : global_scores) {
sb.append(Arrays.toString(row)).append(lineSeparator);
}
String text = sb.toString();
TopScores.append("Global Top 10 Scores\n");
TopScores.append(text);
}//end of onPostExecute
private void readStream(InputStream in) {
BufferedReader reader = null;
try {
StringBuilder htmlIn = new StringBuilder();
StringBuilder globalScoreBuilder = new StringBuilder();
htmlIn.append("");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
htmlIn.append(line);
}
// String to be scanned to find the pattern.
String html = htmlIn.toString();
String regexPattern = "<td align=\"left\" style=\"padding-left:10px;\">(\\d+?)</td>|<td align=\"right\" style=\"padding-right:10px;\">(\\w+?)</td>";
// Create a Pattern object
Pattern patternObject = Pattern.compile(regexPattern);
// Now create matcher object.
Matcher matcherObject = patternObject.matcher(html);
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Trying to find regex matches");
int nextFreePointer = 0;
int rowCount = 0;
while (matcherObject.find()) {
if (matcherObject.group(1) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(1));
globalScoreBuilder.append(matcherObject.group(1) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(1);
nextFreePointer++;
}
if (matcherObject.group(2) != null) {
Log.d(getActivity().getResources().getString(R.string.LOG_TAG), "Regex match : " + matcherObject.group(2));
globalScoreBuilder.append(matcherObject.group(2) + " ");
global_scores[rowCount][nextFreePointer] = matcherObject.group(2);
nextFreePointer++;
}
if (nextFreePointer > 2) {
nextFreePointer = 0;
rowCount++;
}
globalScoreBuilder.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}//end of AsyncOperation inner class
so i have been at it for hours and its 4:07 AM now i have to sleep, so i hope someone can help me.
I have an ArrayList of ImageResults objects the class of which is defined as:
public class ImageResults {
String _title, _country, _thumbnailURL, _imageURL;
public ImageResults(String title, String country, String thumbnailURL, String imageURL)
{
_title = title;
_country = country;
_thumbnailURL = thumbnailURL;
_imageURL = imageURL;
}
public String getTitle()
{
return _title;
}
public String getCountry()
{
return _country;
}
public String getThumbnailURL()
{
return _thumbnailURL;
}
public String getImageURL()
{
return _imageURL;
}
}
Now in order to use https://github.com/thest1/LazyList i have to retrieve the thumbnail urls from my arraylist of type imageresults and place them in an array like im doing here
private void populateListBox()
{
String[] imgLst = new String[imagesList.size()];
for(int i = 0; i < imagesList.size();i++)
{
imgLst[i] = (imagesList.get(i)._thumbnailURL);
// Toast t = Toast.makeText(this,imgLst[0] , Toast.LENGTH_SHORT);
// t.show();
}
adapter=new LazyAdapter(this, imgLst);
imageListView.setAdapter(adapter);
}
now the thing is the way it is above is not working but if i take the link individually as follows it works which is the default way the links are organized in the original project
private void populateListBox()
{
String[] imgLst={
"http://www.istartedsomething.com/bingimages/resize.php?i=Velodrome_EN-AU1182456710.jpg&w=300"};
adapter=new LazyAdapter(this, imgLst);
imageListView.setAdapter(adapter);
}
this is how links are organized in the original project, and yest i am 100% sure that both methods are returning the same string just in different ways, one is fetching it from an object in an arraylist and the other im explicitly declaring it.
private String[] mStrings={
"http://www.istartedsomething.com/bingimages/resize.php?i=Velodrome_EN-AU1182456710.jpg&w=300",
"http://www.istartedsomething.com/bingimages/resize.php?i=Velodrome_EN-CA1182456710.jpg&w=300",
"http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
"http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
"http://a1.twimg.com/profile_images/97470808/icon_normal.png",
"http://a3.twimg.com/profile_images/511790713/AG.png",
"http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
"http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
"http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
"http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg"};
main activity class
public class BngPaperActivity extends Activity {
ListView imageListView;
Spinner countrySpinner;
String selectedMonth;
String selectedYear;
LazyAdapter adapter;
ProgressDialog progress;
Dialog date;
getResult getRes;
String ResultsString;
ArrayList<String> monthList = new ArrayList<String>();
ArrayList<ImageResults> imagesList = new ArrayList<ImageResults>();
String dateText;
TextView selectedDateView;
static final int MONTHYEARDATESELECTOR_ID = 3;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progress = new ProgressDialog(BngPaperActivity.this);
monthList.add("January"); monthList.add("February"); monthList.add("March"); monthList.add("April");
monthList.add("May"); monthList.add("June"); monthList.add("July"); monthList.add("August");
monthList.add("September"); monthList.add("October"); monthList.add("November"); monthList.add("December");
imageListView = (ListView) this.findViewById(R.id.imagesListView);
countrySpinner = (Spinner) this.findViewById(R.id.countrySpinner);
selectedDateView = (TextView) this.findViewById(R.id.selectedDateView);
Button monthYearButton = (Button) this.findViewById(R.id.monthyearBTN);
// set up a listener for when the button is pressed
monthYearButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// call the internal showDialog method using the predefined ID
showDialog(MONTHYEARDATESELECTOR_ID);
}
});
}
private DateSlider.OnDateSetListener mMonthYearSetListener =
new DateSlider.OnDateSetListener() {
public void onDateSet(DateSlider view, Calendar selectedDate) {
// update the dateText view with the corresponding date
dateText = (String.format("%tB %tY", selectedDate, selectedDate));
selectedDateView.setText(dateText);
try {
selectedMonth = monthList.indexOf(String.format("%tB", selectedDate)) + 1 +"";
selectedYear = String.format("%tY", selectedDate);
progress.setMessage("Fetching Images... \nPress Back Button To Cancel");
progress.setCancelable(true);
getRes = new getResult(progress,view);
getRes.execute();
try {
ResultsString = getRes.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
parseResults(ResultsString);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private void parseResults(String result)
{
Scanner scan = new Scanner(result);
String current = scan.nextLine();
String title = "";
String country = "";
String thumbURL = "";
String imageURL = "";
while(!current.equals("End of file"))
{
if(current.equals("Begin Thumb"))
{
current = scan.nextLine();
title = current.substring(current.indexOf(":")+1);
current = scan.nextLine();
country = current.substring(current.indexOf(":")+1);
current = scan.nextLine();
thumbURL = current.substring(current.indexOf(":")+1);
imageURL = thumbURL.replace("300", "900");
current = scan.nextLine();
}
if(current.equals("End Thumb"))
{
imagesList.add(new ImageResults(title,country,thumbURL,imageURL));
}
current = scan.nextLine();
}
populateListBox();
}
private void populateListBox()
{
//this is not working, i would like this one to work
String[] imgLst = new String[imagesList.size()];
for(int i = 0; i < imagesList.size();i++)
{
imgLst[i] = (imagesList.get(i)._thumbnailURL);
// Toast t = Toast.makeText(this,imgLst[0] , Toast.LENGTH_SHORT);
// t.show();
}
//-----------------------------------
/* This is working
String[] imgLst={
"http://www.istartedsomething.com/bingimages/resize.php?i=Velodrome_EN-AU1182456710.jpg&w=300"};
*/
adapter=new LazyAdapter(this, imgLst);
imageListView.setAdapter(adapter);
}
#Override
protected Dialog onCreateDialog(int id) {
// this method is called after invoking 'showDialog' for the first time
// here we initiate the corresponding DateSlideSelector and return the dialog to its caller
final Calendar c = Calendar.getInstance();
final Calendar minDate = Calendar.getInstance();
minDate.set(Calendar.YEAR, 2009);
minDate.set(Calendar.MONTH, Calendar.JUNE);
final Calendar maxDate = Calendar.getInstance();
maxDate.add(Calendar.DATE, 0);
switch (id) {
case MONTHYEARDATESELECTOR_ID:
return new MonthYearDateSlider(this,mMonthYearSetListener,c,minDate,maxDate);
}
return null;
}
private class getResult extends AsyncTask<String, String, String> {
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private ProgressDialog progress;
DateSlider view;
public getResult(ProgressDialog progress, DateSlider view)
{
this.progress = progress;
this.view = view;
}
protected void onPreExecute() {
this.view.dismiss();
this.progress.show();
}
#Override
protected String doInBackground(String... urls) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet("http://devleb.com/BngPaper/BngPaperWebService.php?thumbnail=Yes&year="+selectedYear+"&month="+ selectedMonth));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
//Dialog.dismiss();
progress.dismiss();
return responseString;
}
protected void onPostExecute(Void unused) {
this.progress.dismiss();
if (Error != null) {
Toast.makeText(BngPaperActivity.this, Error, Toast.LENGTH_LONG).show();
}
}
}
}
The following doesn't work?
private void populateListBox()
{
adapter=new LazyAdapter(this, mStrings);
imageListView.setAdapter(adapter);
}
Like in the example given in the lazylist project.
This is my Activity class where i use AsyncTask to get data from a server:
public class UserProfileActivity extends Activity {
private ImageView userImage;
private TextView userName;
private TextView userLocation;
private TextView editInfo;
private TextView chnageImage;
private TextView userScore;
private ListView friendsList;
public ArrayAdapter<String> adapter;
public int score;
public int level;
public String image;
public String fname;
public String lname;
public String city;
public int id;
public String email;
protected Activity activity = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_profile);
userImage = (ImageView) findViewById(R.id.profileImage);
userName = (TextView) findViewById(R.id.userName_profile);
userLocation = (TextView) findViewById(R.id.userLocation_profile);
editInfo = (TextView) findViewById(R.id.edit_profile);
chnageImage = (TextView) findViewById(R.id.changeImage_profile);
userScore = (TextView) findViewById(R.id.userScore_profile);
friendsList = (ListView) findViewById(R.id.friendsList);
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
private InputStream is;
private StringBuilder sb;
private String result;
#Override
protected String doInBackground(String... params) {
try {
HttpPost httppost = new HttpPost(
"http://www.xxxxxxxxx.com/mobile/getProfileInfo");
HttpResponse response = SignUpActivity.httpclient
.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
}
try {
JSONObject jObj = new JSONObject(result);
String status = jObj.getString("status");
score = jObj.getInt("credits");
level = jObj.getInt("level");
image = jObj.getString("image");
fname = jObj.getString("fname");
lname = jObj.getString("lname");
city = jObj.getString("city");
id = jObj.getInt("user_id");
email = jObj.getString("email");
JSONArray friendsJsonArray = jObj.getJSONArray("friends");
int size = friendsJsonArray.length();
ArrayList<String> friendsNames = new ArrayList<String>();
String[] friendsIds = new String[size];
for (int i = 0; i < size; i++) {
friendsNames.add(friendsJsonArray.getJSONObject(i)
.getString("name"));
}
adapter = new ArrayAdapter<String>(getApplicationContext(),
R.layout.simple_listview_item, friendsNames);
} catch (Exception e) {
}
} catch (Exception e) {
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
friendsList.setAdapter(adapter);
userScore.setText(score + " points" + " level " + level);
userName.setText(fname + " " + lname);
userLocation.setText(city);
Bitmap bitmap = null;
try {
bitmap = BitmapFactory
.decodeStream((InputStream) new URL(image).getContent());
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
userImage.setImageBitmap(bitmap);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
}
when this activity is loaded it shows all the default values and images and then changes when background code execution is competed(as excepted), but this takes 2-3 secs for which user will be seeing default values, which i dont want to. So how can i keep a spinner like this:
for 2-3 secs and then when the spinner disappears the activity must show the actual values.
Thank you
Refer the below code
private class FetchRSSFeeds extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(HomeActivity.this);
/** progress dialog to show user that the backup is processing. */
/** application context. */
#Override
protected void onPreExecute() {
this.dialog.setMessage("Please wait");
this.dialog.show();
}
#Override
protected Boolean doInBackground(final String... args) {
try {
Utilities.arrayRSS = objRSSFeed
.FetchRSSFeeds(Constants.Feed_URL);
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
// Setting data to list adapter
setListData();
}
Do This:-
Declare the ProgressDialog at the Top.
ProgressDialog pd;
Start it in onPreExecute Method of Async Task.
pd=ProgressDialog.show(ActivityName.this,"","Please Wait",false);
Stop it in the onPostExecute Method.
pd.dismiss();
In onCreate method call some like below
mdialog=new Dialog(this);
new LongOperation().execute("");
Then override onPostExecute of AyncTask
#Override
protected void onPostExecute() {
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
mdialog.dismiss();
}
});
}
Is it possible to make AsyncTask.doInBackground synchronized - or achieve the same result in another way?
class SynchronizedTask extends AsyncTask {
#Override
protected synchronized Integer doInBackground(Object... params) {
// do something that needs to be completed
// before another doInBackground can be called
}
}
In my case, any AsyncTask.execute() can be started before a previous one has completed, but I need to execute the code in doInBackground only after the previous task has finished.
EDIT: As correctly pointed out, the synchronization works only on the same object instance.
Unfortunately, it is not possible to create an AsyncTask and call execute() more than once on the same object instance, as specified in the "Threading rules" section of the AsyncTask documentation.
The solution is to use a custom Executor to serialize the tasks, or, if you use API 11 or above, AsyncTask.executeOnExecutor(), as suggested in the comments below.
I posted an answer showing an implementation of a SerialExecutor that can be used to queue tasks that will be executed sequentially.
Ideally, I'd like to be able to use AsyncTask.executeOnExecutor() with a SERIAL_EXECUTOR, but this is only available for API level 11 or above:
new AsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);
To target the Android APIs below level 11, I ended up implementing a custom class which encapsulates an ExecutorService with a thread pool size of 1. The full code is open-sourced here.
Executors.newFixedThreadPool(int nThreads) creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. In my case, nThreads is 1, which means tasks can be queued, but only one task will be executed at any given time.
Here is the code:
public abstract class SerialExecutor {
private final ExecutorService mExecutorService;
public SerialExecutor() {
mExecutorService = Executors.newFixedThreadPool(1);
}
public void queue(Context context, TaskParams params) {
mExecutorService.submit(new SerialTask(context, params));
}
public void stop() {
mExecutorService.shutdown();
}
public abstract void execute(TaskParams params);
public static abstract class TaskParams { }
private class SerialTask implements Runnable {
private final Context mContext;
private final TaskParams mParams;
public SerialTask(Context context, TaskParams params) {
mContext = context;
mParams = params;
}
public void run() {
execute(mParams);
Activity a = (Activity) mContext;
a.runOnUiThread(new OnPostExecute());
}
}
/**
* Used to notify the UI thread
*/
private class OnPostExecute implements Runnable {
public void run() {
}
}
}
This can be extended and used as a serial task executor in an Activity:
public class MyActivity extends Activity {
private MySerialExecutor mSerialExecutor;
#Override
public void onCreate(Bundle savedInstanceState) {
// ...
mSerialExecutor = new MySerialExecutor();
}
#Override
protected void onDestroy() {
if (mSerialExecutor != null) {
mSerialExecutor.stop();
}
super.onDestroy();
}
public void onTrigger(int param) {
mSerialExecutor.queue(this, new MySerialExecutor.MyParams(param));
}
private static class MySerialExecutor extends SerialExecutor {
public MySerialExecutor() {
super();
}
#Override
public void execute(TaskParams params) {
MyParams myParams = (MyParams) params;
// do something...
}
public static class MyParams extends TaskParams {
// ... params definition
public MyParams(int param) {
// ... params init
}
}
}
}
You may want to think about using IntentService instead. It seems like it may be a better fit for your process since it has built in features for queuing.
public class RestAsyncTask1 extends AsyncTask<String, Void, String> {
private AsyncTaskCompleteListener callback;
private Context context;
private String method;
private static final AtomicInteger PROGRESS_NUM = new AtomicInteger(0);
private static ProgressDialog PROGRESS_DIALOG;
public RestAsyncTask1(Context context, AsyncTaskCompleteListener callback, String method) {
this.callback = callback;
this.context = context;
this.method = method;
}
public static String format(String url, String... params) {
String[] encoded = new String[params.length];
for (int i = 0; i < params.length; i++) {
encoded[i] = Uri.encode(params[i]);
}
return String.format(url, (String[]) encoded);
}
#Override
protected void onPreExecute() {
int x = PROGRESS_NUM.getAndIncrement();
if (x == 0) {
String title = "M_yug";
PROGRESS_DIALOG = new ProgressDialog(context);
// PROGRESS_DIALOG.setTitle(title);
PROGRESS_DIALOG.setIndeterminate(true);
PROGRESS_DIALOG.setCancelable(false);
PROGRESS_DIALOG.setOnCancelListener(null);
PROGRESS_DIALOG.setMessage("Loading. Please wait...");
PROGRESS_DIALOG.show();
}
}
#Override
protected String doInBackground(String... params) {
String url = params[0];
String response = null;
HttpURLConnection connection = null;
if (params.length > 1) {
if (method.equals(Method.GET)) {
url = format(url, (String[]) Arrays.copyOfRange(params, 1, params.length));
} else if (params.length > 2) {
url = format(url, (String[]) Arrays.copyOfRange(params, 1, params.length - 1));
}
try {
URL call = new URL(url);
connection = (HttpURLConnection) call.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
//connection.setRequestProperty("M-Yug", Utilities.VERSION);
connection.setRequestMethod(method);
connection.setDoOutput(true);
if (method.equals("POST")) {
BufferedOutputStream outputStream = new BufferedOutputStream(connection.getOutputStream());
outputStream.write(params[params.length - 1].getBytes());
outputStream.flush();
}
int status = connection.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
InputStream is = connection.getInputStream();
response = readValue(is);
} else if (status == 400) {
InputStream is = connection.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
Toast.makeText(context, "" + builder.toString(), Toast.LENGTH_SHORT).show();
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
return response;
}
#Override
protected void onPostExecute(String s) {
int x = PROGRESS_NUM.decrementAndGet();
if (x == 0 && PROGRESS_DIALOG != null && PROGRESS_DIALOG.isShowing()) {
PROGRESS_DIALOG.dismiss();
}
if (s!=null) {
String resopnse=s.toString();
callback.onSuccess(resopnse);
} else {
Toast.makeText(context,"Server Not Responding",Toast.LENGTH_SHORT).show();
}
}
private String readValue(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
}
return sb.toString();
}
enum Method {
GET, POST
}
}
AsyncTask is used to run a background thread so that you current process is not interupted .
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
where first of all your doInBackground function iscalled and the returned object will move to on post execute.
which line of code you want to run after some process you can put that in PostExecute function.
this will surely help you