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;
    }
}
}
 
    