2

そもそも; はい、私はどこでもこれに対する答えを探しました、しかし誰も私が持っているのと同じ問題を抱えていません。この質問は、ここにある別の質問と同じように見えるかもしれませんが、間違いなくそうではありません:)

基本的に私が作成したいのは、異なるレイアウトの4つのフラグメントで構成される「ファーストスタート」アクティビティです。これは私がなんとか自分でやることができました。また、ユーザーがデータベースに存在するかどうかを確認するためにリモートサーバーを呼び出すことでフラグメントの1つを支援するAsyncTaskもあります。これも機能します。しかし、電話を回転させて向きを変えるとすぐに、FragmentActivityが再作成されます(明らかに=))。AsyncTaskを起動したときにこれを行うと、クラッシュするか、場合によってはユーザーチェックが終了します。

だから私の質問は:向きが変わった場合にAsyncTaskの状態を保持するにはどうすればよいですか? コールバックを使用し、AsyncTaskを内部クラスとして配置するためのいくつかの基本的なソリューションを見てきました。私の場合、ページャーアダプターのレイアウトと、作成された4つのフラグメントすべてに同じFragmentsクラスが使用されているため、これらは機能しません。

どんな助けでも大歓迎です。例や解決策はさらに高く評価されています!=)

これらすべてを実現する(醜い)コードについては、以下を参照してください。

FirstRunActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.iqqn.***.R;
import com.viewpagerindicator.IconPageIndicator;
import com.viewpagerindicator.PageIndicator;

public class FirstRunActivity extends SherlockFragmentActivity {

private FragmentAdapter mAdapter;
private ViewPager mPager;
private PageIndicator mIndicator;
private boolean userExit = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.first_run);

    mAdapter = new FragmentAdapter(getSupportFragmentManager());

    mPager = (ViewPager)findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);

    mIndicator = (IconPageIndicator)findViewById(R.id.indicator);
    mIndicator.setViewPager(mPager);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.first_run, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_exit:
        userExit = true;
        this.finish();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
};

@Override
public void finish() {
    // Prepare data intent 
    Intent data = new Intent();
    if(userExit) {
        data.putExtra("exit", true);
        setResult(RESULT_CANCELED, data);
    } else {
        data.putExtra("signedIn", true);
        data.putExtra("registered", true);
        data.putExtra("acceptedEULA", true);
        // Activity finished ok, return the data
        setResult(RESULT_OK, data);
    }
    super.finish();
} 
}

FragmentAdapter.java

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import com.iqqn.***.R;
import com.viewpagerindicator.IconPagerAdapter;

class FragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
    protected static final int[] CONTENT = new int[] { R.layout.***_welcome_1, R.layout.***_welcome_2, R.layout.***_welcome_3, R.layout.***_welcome_4};
    protected static final String[] CONTENTTITLE = new String[] { "Welcome","Account","Intro","Let's start!" };
protected static final int[] ICONS = new int[] {
    R.drawable.perm_group_calendar,
    R.drawable.perm_group_camera,
    R.drawable.perm_group_device_alarms,
    R.drawable.perm_group_location
};

private int mCount = CONTENT.length;

public FragmentAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int position) {
    return Fragments.newInstance(CONTENT[position % CONTENT.length],position);
}

@Override
public int getCount() {
    return mCount;
}

@Override
public CharSequence getPageTitle(int position) {
    return FragmentAdapter.CONTENTTITLE[position % CONTENT.length];
}

@Override
public int getIconResId(int index) {
    return ICONS[index % ICONS.length];
}

public void setCount(int count) {
    if (count > 0 && count <= 10) {
        mCount = count;
        notifyDataSetChanged();
    }
}
}

Fragments.java

public final class Fragments extends SherlockFragment {
    private static final String KEY_CONTENT = "Fragments:Content";
private int position = -1;
private RegisterAsyncTaskHelper registerTask = null;

public static Fragments newInstance(int content, int position) {
    Fragments fragment = new Fragments();
    fragment.mContent = content;
    fragment.position = position;
    return fragment;
}

private int mContent = -1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setRetainInstance(true);

    if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
        mContent = savedInstanceState.getInt(KEY_CONTENT);
    }
}

@Override
public void onPause() {

    super.onPause();
}

@Override
public void onResume() {

    super.onResume();
}

@Override
public void onDestroy() {
     if (registerTask != null) {
         registerTask.cancel(false);
     }
    super.onDestroy();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    final View view = inflater.inflate(mContent, container, false);

    switch(position) {
    case 0:
        break;
    case 1:
        final Button btnRegister;
        final Button btnLinkToLogin;

        btnRegister = (Button) view.findViewById(R.id.btnRegister);
        btnLinkToLogin = (Button) view.findViewById(R.id.btnLinkToLoginScreen);
        // Register Button Click event
        btnRegister.setOnClickListener(new View.OnClickListener() {         
            public void onClick(View localview) {
                // Execute register task
                registerTask = new RegisterAsyncTaskHelper(getActivity(), view);
                if(registerTask != null)
                    registerTask.execute();
            }
        });

        // Link to Login Screen
        btnLinkToLogin.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                // TODO Login
            }
        });
        break;
    case 2:
        break;
    case 3:
        break;
    default:
        break;
    }

    return view;
}


@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(KEY_CONTENT, mContent);
}

}

RegisterAsyncTaskHelper.java

import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.iqqn.***.R;
import com.iqqn.***.utils.DatabaseHandler;
import com.iqqn.***.utils.UserFunctions;

public class RegisterAsyncTaskHelper extends AsyncTask<Void, Integer, Void> {

// JSON Response node names
private static final String KEY_SUCCESS = "success";
private static final String KEY_ERROR = "error";
private static final String KEY_ERROR_MSG = "error_msg";
private static final String KEY_UID = "uid";
private static final String KEY_NAME = "name";
private static final String KEY_EMAIL = "email";
private static final String KEY_CREATED_AT = "created_at";

private View view = null;
private FragmentActivity activity = null;
private ProgressBar mProgress;

public RegisterAsyncTaskHelper(FragmentActivity activity, View view) {
    this.view = view;
    this.activity = activity;
    this.mProgress = (ProgressBar) view.findViewById(R.id.registerProgress);
}

@Override
protected void onPreExecute() {
    mProgress.setVisibility(View.VISIBLE);
}

@Override
protected Void doInBackground(Void... params) {

    final EditText inputFullName;
    final EditText inputEmail;
    final EditText inputPassword;
    final TextView registerErrorMsg;

    // Importing all assets like buttons, text fields
    inputFullName = (EditText) view.findViewById(R.id.registerName);
    inputEmail = (EditText) view.findViewById(R.id.registerEmail);
    inputPassword = (EditText) view.findViewById(R.id.registerPassword);
    registerErrorMsg = (TextView) view.findViewById(R.id.register_error);


    String name = inputFullName.getText().toString();
    String email = inputEmail.getText().toString();
    String password = inputPassword.getText().toString();
    UserFunctions userFunction = new UserFunctions();
    JSONObject json = userFunction.registerUser(name, email, password);

    // check for login response
    try {
        if (json.getString(KEY_SUCCESS) != null) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    registerErrorMsg.setText("");
                }
            });

            String res = json.getString(KEY_SUCCESS); 
            if(Integer.parseInt(res) == 1){
                // user successfully registred
                // Store user details in SQLite Database
                DatabaseHandler db = new DatabaseHandler(activity.getApplicationContext());
                JSONObject json_user = json.getJSONObject("user");

                // Clear all previous data in database
                userFunction.logoutUser(activity.getApplicationContext());
                db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));                        

                /*
                // Launch Dashboard Screen
                Intent dashboard = new Intent(ctx, DashboardActivity.class);
                // Close all views before launching Dashboard
                dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(dashboard);
                // Close Registration Screen
                finish();
                 */

            }else{
                // Error in registration
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        registerErrorMsg.setText("Error occured in registration");
                    }
                });
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onProgressUpdate(final Integer... values) {

}

@Override
protected void onPostExecute(final Void result) {
    mProgress.setVisibility(View.GONE);
}
}

明確にするために。このコードは、現時点では決して見栄えがするものではありません。しかし、私がこれを機能させた後、それはそうなるでしょう。

//アレクサンダー

4

4 に答える 4

2

向きが変わった場合にAsyncTaskの状態を保持するにはどうすればよいですか?

保持されたフラグメント(つまり、それ自体AsyncTaskを呼び出す動的フラグメント)によって管理されます。setRetainInstance(true)そのフラグメントは、構成の変更後も存続します。

私の場合、ページャーアダプターのレイアウトと、作成された4つのフラグメントすべてに同じFragmentsクラスが使用されているため、これらは機能しません。

次に、の5番目のフラグメントを追加しAsyncTaskます。UIに参加する必要はありません。

if (getSupportFragmentManager().findFragmentByTag(MODEL)==null) {
  model=new ModelFragment();
  getSupportFragmentManager().beginTransaction().add(model, MODEL)
                             .commit();
}

ここでModelFragmentは、 (および他の場所でメモリに保持されていないアクティビティに必要なデータモデルの任意の部分)をFragment担当します。AsyncTaskタグ()の下にまだ存在しない場合にのみフラグメントを作成しますMODEL

于 2012-11-20T22:41:08.260 に答える
1

AsyncTaskLoaderを使用して、タスクの状態と結果を保存します。

于 2012-11-20T22:28:46.160 に答える
0

このような状況で私が行ったことは、を使用することBroadcastReceiverです。AsyncTaskあなたとあなたを緊密に結合する代わりに、を使用してバックグラウンド操作を実行し、を呼び出してから、そのブロードキャストをあなたで受信することをおFragmentActivity勧めします。Threadcontext.sendBroadcast(...)FragmentActivity

于 2012-11-20T22:32:10.933 に答える
0

ターゲットフラグメントでインテントサービスとLocalBroadcastManagerを使用します

于 2012-11-20T22:44:54.867 に答える