AsyncTask - onProgressUpdate not called until after doInBackground completes - android

I have searched other posts but haven't found any describing my particular problem. Many of them refer to calling publishProgress from doInBackground. I am calling publishProgress from onPreExecute expecting a dialog to be displayed to inform a user that data is being fetched. The AsyncTask is being launched from the user making a selection from a Spinner. Rather than the dialog being displayed, the UI freezes until the AsyncTask completes. I have added in log messages and it appears that although publishProgress is called in onPreExecute, onProgressUpdate is not being executed until after doInBackground is completed.
The activity:
public class MainActivity extends Activity implements OnItemSelectedListener{
private Spinner spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
spinner = (Spinner)findViewById(R.id.spinner);
SpinnerAdapter adapter = new CustomSpinnerAdapter<String>(this, new String[]{"one", "two", "three"});
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#SuppressLint("NewApi")
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
try{
FetchDataTask fetchDataTask = new FetchDataTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
fetchDataTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "data");
} else{
fetchDataTask.execute("data");
}
fetchDataTask.await();
} catch (InterruptedException e){
e.printStackTrace();
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
public class FetchDataTask extends AsyncTask<String, Integer, Boolean> {
private final String TAG = FetchDataTask.class.getSimpleName();
private final Integer FETCHING_DATA = 1;
CountDownLatch countDownLatch = new CountDownLatch(1);
ProgressDialog dialog;
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.d(TAG,"Exiting onPostExecute");
dialog.dismiss();
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
publishProgress(FETCHING_DATA);
Log.d(TAG, "Exiting onPreExecute");
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
dialog = ProgressDialog.show(MainActivity.this, "Fetching", "Data");
Log.d(TAG, "Exiting onProgressUpdate");
}
#Override
protected Boolean doInBackground(String... arg0) {
/*
* Fetching data here
*/
Log.d(TAG, "Exiting doInBackground");
countDownLatch.countDown();
return true;
}
public void await() throws InterruptedException{
countDownLatch.await();
}
}
}
The Spinner:
public class CustomSpinnerAdapter<T> implements SpinnerAdapter {
Context context;
T[] values;
public CustomSpinnerAdapter(Context context, T[] values){
this.context = context;
this.values = values;
for(T value: this.values){
Log.d("Spinner", value.toString());
}
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return values.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return values[position];
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return android.R.layout.simple_spinner_dropdown_item;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
TextView v = new TextView(context);
v.setTextColor(Color.BLACK);
v.setText(values[position].toString());
return v;
}
#Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 1;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
// TODO Auto-generated method stub
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return this.getView(position, convertView, parent);
}
}
The view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
I am think this might have something to do with executing the AsyncTask from the Spinner selection because simply executing it in the Activity without connecting it to the Spinner does not have this problem. Any assistance would be appreciated.

You dont keep on showing dialog on progress update, instead you show it onPreExecute update it onProgressUpdate and hide it onPostExecute or cancel. and in your case you dont need the publish progress since progressBar is indefinite
#Override
protected void onPreExecute()
{
super.onPreExecute();
Log.d(TAG, "Exiting onPreExecute");
dialog = ProgressDialog.show(MainActivity.this, "Fetching", "Data");
}
#Override
protected Boolean doInBackground(String... arg0)
{
Log.d(TAG, "Exiting doInBackground");
countDownLatch.countDown();
//publishProgress(x);
return true;
}
public void await() throws InterruptedException
{
countDownLatch.await();
}
#Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
Log.d(TAG, "Exiting onProgressUpdate");
// update progressbar value
// ex progresssBar.setProgress(values[0]);
}
#Override
protected void onPostExecute(Boolean result)
{
super.onPostExecute(result);
Log.d(TAG,"Exiting onPostExecute");
dialog.dismiss();
}

Related

How to get the context from a function of a class that extends Activity in android?

I have a class that extends Activity, When I try to access the context from the onCreate() method it gets printed but when I save it in a variable context and try to access it from the committext() function as shown below, It prints null. I also tried using "this" and getBaseContext() directly from the committext() function as it is a part of the same class, I get null pointer exception. Please help me figure out what is going wrong.
public class MainKeyboardActionListener extends Activity implements KeyboardView.OnKeyboardActionListener, View.OnTouchListener {
private Context context;
public static boolean active = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mode_keyboard, false);
context=getBaseContext();
System.out.println("contexxtt1"+context);
}
#Override
public void onStart() {
super.onStart();
active = true;
}
#Override
protected void onResume() {
super.onResume();
}
private static class myHandler extends Handler {
}
;
public void setInputConnection(InputConnection ic) {
}
#Override
public void onKey(int arg0, int[] arg1) {
// TODO Auto-generated method stub
}
#Override
public void onPress(int keyCode) {
}
#Override
public void onRelease(int keyCode) {
commitText(String.valueOf(keyCode));
}
private void handleException(int keyCode) {
}
private void removeHalantMode() {
}
private void commitText(String text) {
if(active==true) {
System.out.println("contexxtt"+context);
}
}
#Override
public void onText(CharSequence arg0) {
// TODO Auto-generated method stub
}
#Override
public void swipeDown() {
// TODO Auto-generated method stub
}
#Override
public void swipeLeft() {
// TODO Auto-generated method stub
}
#Override
public void swipeRight() {
// TODO Auto-generated method stub
}
#Override
public void swipeUp() {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void onStop() {
super.onStop();
active = false;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Make your myHandler class not static.

Android Service - Three different song is playing for one image

Hi I am creating a application for kids, It shows a Alphabets(Images) from A to Z in GridView. If u click S it will open the S in separate activity where you can swipe S to T,V,U...etc.. or You can swipe back to R,Q,P... etc.. And it has to play the song for S if u open S(For eg, S for Something). I achieved this using ViewPager.
What my problem is if I click S its playing the song for all R,S,T instead of playing a single track.
I don't know How to Fix it???
MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridView = (GridView) findViewById(R.id.grid_view);
// Instance of ImageAdapter Class
gridView.setAdapter(new ImageAdapter(this));
/**
* On Click event for Single Gridview Item
* */
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
// Sending image id to FullScreenActivity
Intent i = new Intent(getApplicationContext(), IndividualAlphabet.class);
// passing array index
i.putExtra("id", position);
startActivity(i);
}
});
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
startService(new Intent(MainActivity.this,MediaPlayerService.class));
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
startService(new Intent(MainActivity.this,MediaPlayerService.class));
}
}
Service (This is for Song)
public class MediaPlayerService extends Service{
MediaPlayer myMediaPlayer;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show();
myMediaPlayer=MediaPlayer.create(getApplicationContext(),R.raw.alphabets);
myMediaPlayer.setLooping(false);
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
myMediaPlayer.start();
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show();
myMediaPlayer.stop();
}
}
For Individual Activity
public class IndividualAlphabet extends Activity {
private String[] alphabets;
public static int[] mRaw = {
R.raw.a,R.raw.b,R.raw.c,R.raw.d,R.raw.e,R.raw.f,R.raw.g,R.raw.h,R.raw.i,R.raw.j,
R.raw.k,R.raw.l,R.raw.m,R.raw.n,R.raw.o,R.raw.p,R.raw.q,R.raw.r,R.raw.s,R.raw.t,
R.raw.u,R.raw.v,R.raw.w,R.raw.x,R.raw.y,R.raw.z
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_individual_alphabet);
// get intent data
Intent i = getIntent();
// Selected image id
int position = i.getExtras().getInt("id");
SwipeImageAdapter adapter = new SwipeImageAdapter(this);
ViewPager myPager = (ViewPager) findViewById(R.id.pager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(position);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.individual_alphabet, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void playSong() {
startService(new Intent(IndividualAlphabet.this,MediaPlayerService.class));
}
public void stopSong() {
stopService(new Intent(IndividualAlphabet.this,MediaPlayerService.class));
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
stopSong();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
stopService(new Intent(IndividualAlphabet.this,MediaPlayerService.class));
}
#Override
public void finish() {
// TODO Auto-generated method stub
super.finish();
stopService(new Intent(IndividualAlphabet.this,MediaPlayerService.class));
}
}
And for Swipe Adapter
public class SwipeImageAdapter extends PagerAdapter{
Activity activity;
Context context;
public static int[] mThumbIds = {
R.drawable.a, R.drawable.b,
R.drawable.c, R.drawable.d,
R.drawable.e, R.drawable.f,
R.drawable.g, R.drawable.h,
R.drawable.i, R.drawable.j,
R.drawable.k, R.drawable.l,
R.drawable.m, R.drawable.n,
R.drawable.o,R.drawable.p,
R.drawable.q,R.drawable.r,
R.drawable.s,R.drawable.t,
R.drawable.u,R.drawable.v,
R.drawable.w,R.drawable.x,
R.drawable.y,R.drawable.z
};
public static int[] mRaw = {
R.raw.a,R.raw.b,
R.raw.c,R.raw.d,
R.raw.e,R.raw.f,
R.raw.g,R.raw.h,
R.raw.i,R.raw.j,
R.raw.k,R.raw.l,
R.raw.m,R.raw.n,
R.raw.o,R.raw.p,
R.raw.q,R.raw.r,
R.raw.s,R.raw.t,
R.raw.u,R.raw.v,
R.raw.w,R.raw.x,
R.raw.y,R.raw.z
};
public SwipeImageAdapter(Activity act) {
this.activity = act;
this.context=act.getBaseContext();
}
public int getCount() {
return mThumbIds.length;
}
#SuppressWarnings("deprecation")
public Object instantiateItem(View collection, int position) {
ImageView view = new ImageView(activity);
view.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
view.setScaleType(ScaleType.FIT_CENTER);
view.setImageResource(mThumbIds[position]);
view.setPadding(10, 10, 10, 10);
((ViewPager) collection).addView(view, 0);
MediaPlayer mp5 = MediaPlayer.create(activity.getBaseContext(),mRaw[position]);
mp5.start();
return view;
}
#Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
#Override
public Parcelable saveState() {
return null;
}
}
Someone help me to fix this app...

using gridview inside a runnable gives error

Can somebody explain how to use the GridView inside a Runnable.
Handler starthandler = new Handler();
Runnable startrun= new Runnable(){
#Override
public void run() {
G1=(GridView)findViewById(R.id.balloongrid);
G1.setAdapter(new BalloonImageAdaper(this));
}
};
The above code gives the following error:
The constructor Cacrballoonclass.BalloonImageAdaper(new Runnable(){}) is undefined
public class BalloonImageAdaper extends BaseAdapter{ // create a class by name
imageadapter so as to fill the gridview with data
private Context ballooncontext;
public BalloonImageAdaper (Context c) {
ballooncontext = c;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return balloonthumbs.length;
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
ImageView balloonimageview;
if(arg1==null){
balloonimageview = new ImageView(ballooncontext);
balloonimageview.setLayoutParams(new GridView.LayoutParams(75,75));
balloonimageview.setScaleType(ImageView.ScaleType.CENTER_CROP);
balloonimageview.setPadding(7, 7, 7, 7);
}else {
balloonimageview = (ImageView)arg1;
}
// lets inflate balloon randomly
int rballoon = new Random().nextInt(ballooninstruct.length);
balloonimageview.setImageResource(balloonthumbs[rballoon]);
balloonimageview.setTag(balloonthumbs[rballoon]);
return balloonimageview;
}
}// class imageAdapter extends baseadapter
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onResume();
finish();
}
}//class ends cacrballoonclasss
Replace
new BalloonImageAdaper(this)
with
new BalloonImageAdaper(mContext) // mContext: reference to any Context (Activity or whatever)
(If that's inside an Activity you can use NameOfActivity.this.)
The this inside your Runnable is referring to your Runnable and not, like I assume you want it to reference to, your Activity.

Fragment instance retain in android

in main activiy i call a fragment and in fragment iam displaying a progress dialog in async task now my question is when orientation change my progress dialog restart and i want it retain its state iam using a retainInstance(true) but its not working.
my fragment code is
#Override
public void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setRetainInstance(true);
if(savedInstanceState!=null)
{
if(pDialog!=null)
{
pDialog.show();
}
}
}
#Override
public void onSaveInstanceState(Bundle outState)
{
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putString("status", "ok");
}
public void showProgress()
{
pDialog = new ProgressDialog(getActivity());
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setMessage("Processing...");
pDialog.setCancelable(false);
pDialog.setMax(900000000);
pDialog.show();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View view=inflater.inflate(R.layout.fragment, container, false);
proceed=(Button) view.findViewById(R.id.b1);
proceed.setOnClickListener(this);
return view;
}
#Override
public void onClick(View v)
{
new inner().execute();
}
class inner extends AsyncTask
{
#Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
showProgress();
}
#Override
protected Object doInBackground(Object... arg0)
{
int k=0;
for(int i=0;i<10000000;i++)
{
pDialog.incrementProgressBy(i);
for(int j=0;j<10000;j++)
{
k=k+j;
}
}
// TODO Auto-generated method stub
return null;
}
#Override
protected void onPostExecute(Object result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
System.out.println("enter here");
pDialog.dismiss();
}
}
#Override
public void onPause()
{
// TODO Auto-generated method stub
super.onPause();
}
#Override
public void onStop()
{
// TODO Auto-generated method stub
super.onStop();
if (pDialog!=null && pDialog.isShowing()){
pDialog.dismiss();
}
}
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
}
You have to save your current progress in onDetach and use it again in onAttach. Example:
private ProgressDialog buildDialog() {
progressDialog = new ProgressDialog(getActivity());
progressDialog.setCancelable(false);
progressDialog.setTitle(getResources().getString(R.string.please_wait));
progressDialog.setIndeterminate(false);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setProgress(currentProgress);
progressDialog.setMax(100);
return progressDialog;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
attached = true;
if (taskStarted) {
progressDialog = this.buildDialog();
progressDialog.setMessage(getResources().getString(messageId));
progressDialog.show();
}
}
#Override
public void onDetach() {
super.onDetach();
if (progressDialog != null && progressDialog.isShowing()) {
currentProgress = progressDialog.getProgress();
progressDialog.dismiss();
progressDialog = null;
}
attached = false;
}
I wrote an example of this the other day. Here you go
https://gist.github.com/slightfoot/11368894

Show indefinite progress cycle on the Activity

I'd like my application to show the indefinite progress bar (you know, the cycle) into the Activity's layout, just like the youtube Application. How could I do that? Thanks.
Hi you can use setProgressBarIndeterminateVisibility(boolean) to show indefinite progress bar.Here is the sample code:
private Button buttonUpStartUpload = null;
private boolean mToggleIndeterminate = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.lyt_upload_main);
setProgressBarIndeterminateVisibility(mToggleIndeterminate);
buttonUpStartUpload = (Button) findViewById(R.id.buttonUpStartUpload);
buttonUpStartUpload.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
UploadingAsyncTask uploadingAsyncTask = new UploadingAsyncTask();
uploadingAsyncTask.execute("temp","doinback","returnparam");
}
});
}//onCreate Ends
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
public class UploadingAsyncTask extends AsyncTask<String, String, String>{
Uploader uploader = new Uploader();
ProgressDialog progDialogUpload = null;
int imageIndex = 1;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
mToggleIndeterminate = !mToggleIndeterminate;
setProgressBarIndeterminateVisibility(mToggleIndeterminate);
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
publishProgress("Finish","3");
return "success";
}
#Override
protected void onProgressUpdate(String... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
if(values[0] == "Finish"){
imageIndex++;
}
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(result.equalsIgnoreCase("success") || result == "success"){
mToggleIndeterminate = !mToggleIndeterminate;
setProgressBarIndeterminateVisibility(mToggleIndeterminate);
}
}
}//UploadingAsyncTask ends

Categories

Resources