I need to show a ProgressDialog which will show even after rotation of activity. After rotation of the activity progressDialog is keep displaying, it doesn't get dismissed even after I signal it to dismiss by invoking idle(). what could be the reason. Thanks in advance!
public abstract class BaseActivity extends AppCompatActivity {
private final int command = 1;
private final String action = "show-progress-dialog";
private boolean showProgress = false;
private volatile ProgressDialog progressDialog;
private Handler mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message message) {
if (message.getData() != null && message.what == command) {
if (message.getData().getBoolean("show")) {
showProgressDialog();
} else {
safeDismiss();
}
}
}
};
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("showProgress", showProgress);
safeDismiss();
super.onSaveInstanceState(outState);
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showProgress = savedInstanceState != null && savedInstanceState.getBoolean("showProgress", false);
if (showProgress) {
showProgressDialog();
}
}
protected void busy() {
if (Looper.getMainLooper() == Looper.myLooper()) {//in ui thread
showProgressDialog();
return;
}
Message message = mHandler.obtainMessage(command);
Bundle data = new Bundle();
data.putBoolean("show", true);
data.putString("action", action);
message.setData(data);
message.sendToTarget();
}
protected void idle() {
if (Looper.getMainLooper() == Looper.myLooper()) {//in ui thread
safeDismiss();
return;
}
Message message = mHandler.obtainMessage(command);
Bundle data = new Bundle();
data.putBoolean("show", false);
data.putString("action", action);
message.setData(data);
message.sendToTarget();
}
private void showProgressDialog() {
safeDismiss();
progressDialog = ProgressDialog.show(this, null, "please wait…", true, false);
showProgress = true;
}
private void safeDismiss() {
if (progressDialog != null) {
progressDialog.dismiss();
showProgress = false;
progressDialog = null;
}
}
}
Read android:configChanges
When a configuration change occurs at runtime, the activity is shut
down and restarted by default, but declaring a configuration with this
attribute will prevent the activity from being restarted.
<activity
android:name=".ActivityName"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name" >
</activity>
Then
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (progressDialog.isShowing())
{
progressDialog .dismiss();
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
if (progressDialog.isShowing())
{
progressDialog .dismiss();
}
}
}
Related
I am running a simple handler and even when I do a handler.sendMessage(), the handleMessage method is not called.
Here is the Handler definition:
protected static class TimeoutHandler extends Handler {
private final WeakReference<PROQuestion> activity;
public TimeoutHandler(PROQuestion activity) {
this.activity = new WeakReference<PROQuestion>(activity);
}
#Override
public void handleMessage(Message msg) { //never gets called
boolean firstScreen = true;
if (activity.get() == null) {
removeCallbacksAndMessages(0);
} else {
Intent startNewActivityOpen = null;
startNewActivityOpen = new Intent(activity.get(), Home.class);
startNewActivityOpen.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = activity.get().getIntent().getExtras();
if (bundle != null) startNewActivityOpen.putExtras(bundle);
activity.get().startActivity(startNewActivityOpen);
activity.get().finish();
}
}
I am calling the handler on the main thread of my onCreate():
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TimeoutHandler handlerTimeout = new TimeoutHandler(this);
if (handlerTimeout != null) {
removeTimeout();
Message message = handlerTimeout.obtainMessage();
message.what = 100;
handlerTimeout.sendMessage(message);
//handlerTimeout.sendMessageAtTime(message, SystemClock.uptimeMillis() + GlobalVars.longTimeout);
}
if (handlerTimeout.hasMessages(100)) { //returns true
Log.d(getClass().getSimpleName(),"messages found");
}
}
Why is the handleMessage method never called? There are no error messages or crashes.
I have an activity with a button that starts an AsyncTask:
public void search(View view) {
if (searchTask != null) {
return;
}
searchTask = new SearchTask(this);
searchTask.execute((Void)null);
}
And this is the task:
public class SearchTask extends AsyncTask<Void, Void, Boolean> {
private final Activity activity;
private final ProgressDialog dialog;
public SearchTask(Activity activity) {
this.activity = activity;
this.dialog = new ProgressDialog(activity);
}
#Override
protected Boolean doInBackground(Void... params) {
try {
wait(3000);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
#Override
protected void onPreExecute() {
dialog.show();
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing())
dialog.dismiss();
}
}
I'm not calling get() so I shouldn't be blocking the UI thread. The problem is that the progress dialog is not being shown.
Is this not the correct way to show a dialog within an AsynTask?
wait() causes IllegelMonitorException. to apply a delay in the task Thread.sleep() should be used.
try after removing return; from below code-
public void search(View view) {
if (searchTask != null) {
return;
}
searchTask = new SearchTask(this);
searchTask.execute((Void)null);
}
I have a trouble with getting Activity(Nullpointerexception) after that I have rotate screen and received callback from AsyncTask to update my views of the fragment. If I wont change orientation then everything is OK(but not all the time, sometimes this bug appears)
My main activity:
public class MainActivity extends SherlockFragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager_layout);
fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(this);
session = new SessionManager(getApplicationContext());
if (session.isAuthorizated()) {
disableTabs();
FragmentTransaction ft = fm.beginTransaction();
if (session.termsAndConditions()) {
ft.replace(android.R.id.content, new TermsAndConditionsFragment(), "terms-and-conditions").commit();
}
}
} else {
enableTabs();
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(actionBar.newTab().setText("Log in"), LoginFragment.class, null);
mTabsAdapter.addTab(actionBar.newTab().setText("Calculator"), CalculatorFragment.class, null);
}
}
That`s my fragment:
public class TermsAndConditionsFragment extends SherlockFragment implements OnClickListener, OnTouchListener, OnEditorActionListener, ValueSelectedListener, AsyncUpdateViewsListener {
private static final String TAG = "TermsAndConditionsFragment";
private TermsAndConditionsManager termsAndConditionsM;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prepareData();
}
public void prepareData() {
if (getSherlockActivity() == null)
Log.d(TAG, "Activity is null");
termsAndConditionsM = new TermsAndConditionsManager(getSherlockActivity().getApplicationContext());
termsAndConditions = termsAndConditionsM.getTermsAndConditions();
...
// some stuff
...
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = init(inflater, container);
return rootView;
}
private View init(LayoutInflater inflater, ViewGroup container) {
rootView = inflater.inflate(R.layout.fragment_terms_and_conditions, container, false);
//bla bla bla
return rootView;
}
public void updateTermsAndConditionsView() {
//update views here
}
#Override
public void onClick(View v) {
ft = fm.beginTransaction();
switch (v.getId()) {
case R.id.etHowMuch:
d = NumberPaymentsPickerFragment.newInstance(getSherlockActivity(), Integer.valueOf(howMuch.replace("£", "")), 0);
d.setValueSelectedListener(this);
d.show(getFragmentManager(), Const.HOW_MUCH);
break;
}
}
#Override
public void onValueSelected() {
Bundle args = new Bundle();
...
ExecuteServerTaskBackground task = new ExecuteServerTaskBackground(getSherlockActivity());
task.setAsyncUpdateViewsListener(this);
task.action = ServerAPI.GET_TERMS_AND_CONDITIONS;
task.args = args;
task.execute();
}
#Override
public void onUpdateViews() {
prepareData();
updateTermsAndConditionsView();
}
}
My AsyncTask with callback:
public class ExecuteServerTaskBackground extends AsyncTask<Void, Void, Void> {
private static final String TAG = "ExecuteServerTaskBackground";
Activity mActivity;
Context mContext;
private AsyncUpdateViewsListener callback;
public ExecuteServerTaskBackground(Activity activity) {
this.mActivity = activity;
this.mContext = activity.getApplicationContext();
}
public void setAsyncUpdateViewsListener(AsyncUpdateViewsListener listener) {
callback = listener;
}
#Override
protected Void doInBackground(Void... params) {
ServerAPI server = new ServerAPI(mContext);
if (!args.isEmpty())
msg = server.serverRequest(action, args);
else
msg = server.serverRequest(action, null);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
callback.onUpdateViews();
}
}
Why does it behave so? How can I get activity correctly if I change orientation.
EDIT:
As I understand correctly nullpointer appears after orientation changed and asynctask executed due to wrong reference between asyctask and Activity. Recreated activity doesnt have this reference thats why when I receive callback I use wrong activity reference which isn`t exist anymore. But how can I save current activity reference?
EDIT:
I have decided to try realize my task throughout Service and that`s what I have done.
Activity:
public class MainFragment extends Fragment implements ServiceExecutorListener, OnClickListener {
private static final String TAG = MainFragment.class.getName();
Button btnSend, btnCheck;
TextView serviceStatus;
Intent intent;
Boolean bound = false;
ServiceConnection sConn;
RESTService service;
ProgressDialog pd = new ProgressDialog();
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
intent = new Intent(getActivity(), RESTService.class);
getActivity().startService(intent);
sConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.d(TAG, "MainFragment onServiceConnected");
service = ((RESTService.MyBinder) binder).getService();
service.registerListener(MainFragment.this);
if (service.taskIsDone())
serviceStatus.setText(service.getResult());
bound = true;
}
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "MainFragment onServiceDisconnected");
bound = false;
}
};
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.main_fragment, container, false);
serviceStatus = (TextView) rootView.findViewById(R.id.tvServiceStatusValue);
btnSend = (Button) rootView.findViewById(R.id.btnSend);
btnCheck = (Button) rootView.findViewById(R.id.btnCheck);
btnSend.setOnClickListener(this);
btnCheck.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSend:
pd.show(getFragmentManager(), "ProgressDialog");
service.run(7);
service.run(2);
service.run(4);
break;
case R.id.btnCheck:
if (service != null)
serviceStatus.setText(String.valueOf(service.taskIsDone()) + service.getTasksCount());
break;
}
}
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "Bind service");
getActivity().bindService(intent, sConn, 0);
}
#Override
public void onPause() {
super.onDestroy();
Log.d(TAG, "onDestroy: Unbind service");
if (!bound)
return;
getActivity().unbindService(sConn);
service.unregisterListener(this);
bound = false;
}
#Override
public void onComplete(String result) {
Log.d(TAG, "Task Completed");
pd.dismiss();
serviceStatus.setText(result);
}
}
Dialog:
public class ProgressDialog extends DialogFragment implements OnClickListener {
final String TAG = ProgressDialog.class.getName();
public Dialog onCreateDialog(Bundle savedInstanceState) {
setRetainInstance(true);
AlertDialog.Builder adb = new AlertDialog.Builder(getActivity())
.setTitle("Title!")
.setPositiveButton(R.string.yes, this)
.setNegativeButton(R.string.no, this)
.setNeutralButton(R.string.maybe, this)
.setCancelable(false)
.setMessage(R.string.message_text)
.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
return true;
}
});
return adb.create();
}
public void onClick(DialogInterface dialog, int which) {
int i = 0;
switch (which) {
case Dialog.BUTTON_POSITIVE:
i = R.string.yes;
break;
case Dialog.BUTTON_NEGATIVE:
i = R.string.no;
break;
case Dialog.BUTTON_NEUTRAL:
i = R.string.maybe;
break;
}
if (i > 0)
Log.d(TAG, "Dialog 2: " + getResources().getString(i));
}
public void onDismiss(DialogInterface dialog) {
Log.d(TAG, "Dialog 2: onDismiss");
// Fix to avoid simple dialog dismiss in orientation change
if ((getDialog() != null) && getRetainInstance())
getDialog().setDismissMessage(null);
super.onDestroyView();
}
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
Log.d(TAG, "Dialog 2: onCancel");
}
}
Service:
public class RESTService extends Service {
final String TAG = RESTService.class.getName();
MyBinder binder = new MyBinder();
ArrayList<ServiceExecutorListener> listeners = new ArrayList<ServiceExecutorListener>();
Handler h = new Handler();
RequestManager mRequest;
ExecutorService es;
Object obj;
int time;
StringBuilder builder;
String result = null;
public void onCreate() {
super.onCreate();
Log.d(TAG, "RESTService onCreate");
es = Executors.newFixedThreadPool(1);
obj = new Object();
builder = new StringBuilder();
}
public void run(int time) {
RunRequest rr = new RunRequest(time);
es.execute(rr);
}
class RunRequest implements Runnable {
int time;
public RunRequest(int time) {
this.time = time;
Log.d(TAG, "RunRequest create");
}
public void run() {
Log.d(TAG, "RunRequest start, time = " + time);
try {
TimeUnit.SECONDS.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Log.d(TAG, "RunRequest obj = " + obj.getClass());
} catch (NullPointerException e) {
Log.d(TAG, "RunRequest error, null pointer");
}
builder.append("result " + time + ", ");
result = builder.toString();
sendCallback();
}
}
private void sendCallback() {
h.post(new Runnable() {
#Override
public void run() {
for (ServiceExecutorListener listener : listeners)
listener.onComplete();
}
});
}
public boolean taskIsDone() {
if (result != null)
return true;
return false;
}
public String getResult() {
return result;
}
public void registerListener(ServiceExecutorListener listener) {
listeners.add(listener);
}
public void unregisterListener(ServiceExecutorListener listener) {
listeners.remove(listener);
}
public IBinder onBind(Intent intent) {
Log.d(TAG, "RESTService onBind");
return binder;
}
public boolean onUnbind(Intent intent) {
Log.d(TAG, "RESTService onUnbind");
return true;
}
public class MyBinder extends Binder {
public RESTService getService() {
return RESTService.this;
}
}
}
As you mention in your edit, the current Activity is destroyed and recreated on orientation change.
But how can I save current activity reference?
You shouldn't. The previous Activity is no longer valid. This will not only cause NPEs but also memory leaks because the AsyncTask might hold the reference to old Activity, maybe forever.
Solution is to use Loaders.
This is my little test program. My problem is that from run() method I access to fields of wrong (old) Activity, which was destroyed after screen orientation changed. What's the way to handle this situation?
And, by the way, I must have my activity been recreated, because in real application I have different layouts for portrait and landscape modes!
public class MainActivity extends Activity {
private EditText edit;
private Button button;
private ProgressDialog progressDialog;
private boolean isLoginInProgress = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit_timer);
button = (Button) findViewById(R.id.btn_start);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
if (edit.getText().toString().length() == 0) throw new Exception();
long dTime = Long.parseLong(edit.getText().toString());
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
MainActivity.this.isLoginInProgress = false;
progressDialog.dismiss();
}
}, dTime);
progressDialog.show();
isLoginInProgress = true;
} catch (Exception e) {
Toast.makeText(MainActivity.this, "bad time value", Toast.LENGTH_SHORT).show();
}
}
});
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("loading");
if (savedInstanceState != null) { // activity is restarted
isLoginInProgress = savedInstanceState.getBoolean("fl_login");
edit.setText(savedInstanceState.getString("edit"));
}
if (isLoginInProgress) { // Show dialog again
progressDialog.show();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("fl_login", isLoginInProgress);
outState.putString("edit", edit.getText().toString());
}
#Override
public void onDestroy(){
super.onDestroy();
progressDialog.dismiss();
}
}
You Can Use Database(SQLITE) for Storing Your Values..
I have an Handler registered in an Activity. handleMessage() calls notifyDataSetChanged on an Adapter. Things work while the Activity has initial focus. However, when I navigate out of the Activity and back in, notifyDataSetChanged() does not work.
FileAdapter is an ArrayAdapter. MergeAdapter is a custom class by CommonsWare. _mergeAdapter contains _fileAdapter.
Activity code:
public void setUpDownloadHandler() {
// Define the Handler that receives messages from the thread and update the progress
_downloadHandler = new Handler() {
public void handleMessage(Message message) {
super.handleMessage(message);
String fileId = (String) message.obj;
int progress = message.arg1;
FileInfo tempFile = null;
for (FileInfo file: _files) {
if (file.getFileId().equals(fileId)) {
file.setDownloadProgress(progress);
tempFile = file;
}
}
if (tempFile != null) {
_files.remove(tempFile);
_files.add(tempFile);
}
_fileAdapter.notifyDataSetChanged();
_mergeAdapter.notifyDataSetChanged();
}
};
}
Passing the handler:
RunnableTask task = new DownloadFileRunnableImpl(application, the_workspace_url, the_file_info, the_workspace_info.getTitle(), the_internal_storage_directory,
_downloadHandler);
Background thread code:
if(temp > previous) {
Message message = new Message();
message.arg1 = _currentProgress.intValue();
message.obj = _fileId;
_progressHandler.sendMessage(message);
previous = temp;
}
The other piece of information is that I'm passing the handler through a Binder and then into the runnable. I do this to run the background thread in a Service. I don't think this is the problem.
EDIT:
It seems like the handler is not associated with the activity the second time it is navigated to (perhaps because onCreate creates a new handler). Is there a way to re-associate or retain the old handler?
Update
The activity is being destroyed when it loses focus to another activity.
I would try putting a log message in your activity's onDestroy method to see if it is getting destroyed, when you navigate away from your activity. So your task may have the handler from the old activity.
Here is my answer, I relied heavily on http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.html
Really just took their code and changed it so that I have to remake the fragment everytime I want to start the thread (work) again. And it communicates with the Activity through a handler.
public class Main extends Activity implements WorkProgressListener {
private static final String TAG = "tag";
private Handler handler;
private Button startWorkBtn;
private ProgressDialog progressDialog;
private boolean onSaveInstanceFlag = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG,"Main onCreate " + Utils.getThreadId());
setContentView(R.layout.main);
handler = new ProgressHandler();
startWorkBtn = (Button)this.findViewById(R.id.start_work_btn);
startWorkBtn.setEnabled(false);
startWorkBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick (View v) {
Log.i("tag","Main: startWorkBtn onClick ");
startWorkBtn.setEnabled(false);
FragmentManager fm = getFragmentManager();
Fragment workF = (Fragment)fm.findFragmentByTag("work");
if (null == workF) {
workF = new WorkFragment();
Log.i(TAG,"Main new WorkF" + Utils.getThreadId());
startProgressDialog(true);
startWorkBtn.setEnabled(false);
fm.beginTransaction().add(workF, "work").commit();
Log.i(TAG,"Main add(workF) " + Utils.getThreadId());
}
else {
// should never be able to get here.
}
}
});
FragmentManager fm = getFragmentManager();
Fragment loadingFragment = fm.findFragmentByTag("work");
Log.i(TAG,"Main findFragment " + Utils.getThreadId());
if (null == loadingFragment) {
this.startWorkBtn.setEnabled(true);
}
else {
// could also decide to show progress dialog based on savedInstanceState
this.startProgressDialog(true);
}
} // end onCreate
#Override
public void onRestart() {
Log.i(TAG,"Main onRestart " + Utils.getThreadId() );
super.onRestart();
this.onSaveInstanceFlag = false;
}
#Override
public void onResume () {
Log.i(TAG,"Main onResume " + Utils.getThreadId());
super.onResume();
this.onSaveInstanceFlag = false;
}
#Override
public void onSaveInstanceState (Bundle savedInstanceState) {
Log.i(TAG,"Main onSaveInstanceState "+ Utils.getThreadId());
this.onSaveInstanceFlag = true;
super.onSaveInstanceState(savedInstanceState);
if (null != this.progressDialog) {
savedInstanceState.putBoolean("progressDialog", true);
}
else {
savedInstanceState.putBoolean("progressDialog", false);
}
}
#Override
public void onStop () {
Log.i(TAG,"Main onStop " + Utils.getThreadId());
super.onStop();
}
#Override
public void onDestroy () {
Log.i(TAG,"Main onDestroy " + Utils.getThreadId());
super.onDestroy();
this.closeProgressDialog();
this.handler.removeCallbacksAndMessages(null);
}
public class ProgressHandler extends Handler {
#Override
public void handleMessage (Message msg) {
Log.i(TAG,"Main ProgressDialogHandler handleMessage");
Bundle b = msg.getData();
boolean isDone = b.getBoolean("isDone");
String tag = b.getString("tag");
if (isDone && !onSaveInstanceFlag) {
FragmentManager fm = getFragmentManager();
Fragment loader = (Fragment)fm.findFragmentByTag(tag);
fm.beginTransaction().remove(loader).commit();
closeProgressDialog();
Main.this.startWorkBtn.setEnabled(true);
}
}
}
#Override
public void sendProgress(String tag, int progress, int max) {
if ( progress == max) {
Log.i(TAG,"Main sendProgress " + Utils.getThreadId());
Message message = handler.obtainMessage();
Bundle b = new Bundle();
b.putBoolean("isDone", true);
b.putString("tag",tag);
message.setData(b);
this.handler.sendMessage(message);
}
}
private void startProgressDialog(boolean show) {
this.progressDialog = new ProgressDialog(this);
this.progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
this.progressDialog.setMessage("loading");
this.progressDialog.setCancelable(false);
this.progressDialog.show();
}
private void closeProgressDialog() {
if (null != this.progressDialog) {
progressDialog.cancel();
this.progressDialog = null;
}
}
} // end Main
public class WorkFragment extends Fragment {
private static final String TAG = "tag";
private boolean mReady = false;
private boolean mQuiting = false;
private boolean done = false;
public WorkFragment () {}
final Thread mThread = new Thread() {
#Override
public void run () {
synchronized(this) {
while (!mReady) {
Log.i(TAG,"WorkF notReady"+ Utils.getThreadId());
if (mQuiting) {
return;
}
try {
wait();
} catch (InterruptedException e) {
}
}
} // end synchronized
Log.i(TAG,"WorkF starting work "+ Utils.getThreadId());
try {
Log.i(TAG,"WorkF about to sleep"+ Utils.getThreadId());
Thread.currentThread().sleep(10000l);
Log.i(TAG,"WorkF almost finished "+ Utils.getThreadId());
done = true;
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized(this) {
while (!mReady) {
Log.i(TAG,"Activity notReady"+ Utils.getThreadId());
if (mQuiting) {
return;
}
try {
wait();
} catch (InterruptedException e) {
}
}
((WorkProgressListener)getActivity()).sendProgress(WorkFragment.this.getTag(), 100, 100);
} // end synchronized 2
}
};
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.i(TAG,"WorkF, onAttach: "+ Utils.getThreadId());
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG,"WorkF, onCreate: "+ Utils.getThreadId());
setRetainInstance(true);
mThread.start();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(TAG,"WorkF, onActivityCreated: "+ Utils.getThreadId());
if (done) {
((WorkProgressListener)getActivity()).sendProgress(WorkFragment.this.getTag(), 100, 100);
}
synchronized (mThread) {
mReady = true;
mThread.notify();
}
}
#Override
public void onStart()
{
super.onStart();
Log.i(TAG,"WorkF, onStart: "+ Utils.getThreadId() );
}
#Override
public void onDestroy() {
synchronized (mThread) {
mReady = false;
mQuiting = true;
mThread.notify();
}
super.onDestroy();
}
#Override
public void onDetach() {
synchronized (mThread) {
mReady = false;
mThread.notify();
}
super.onDetach();
}
public void restart() {
synchronized (mThread) {
mThread.notify();
}
}
}// end WorkFragment
public interface WorkProgressListener {
public void sendProgress (String tag, int progress, int max);
}