我正在尝试将Fragment传递给ASyncTask类,以便在任务完成后我可以更新片段中的一个或两个小部件。这就是我正在处理的事情:
public class LoginFragment extends Fragment {
Button loginButton;
TextView loginErrorMsg;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.loginfragment, container, false);
}
public OnClickListener loginListener = new OnClickListener() {
@Override
public void onClick(View v) {
Log.v("LoginF", "onclick");
ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Logging in...");
LoginTask loginTask = new LoginTask((Polling) getActivity(), progressDialog);
loginTask.execute();
}
};
LoginTask:
public class LoginTask extends AsyncTask<String, Void, Integer> {
private ProgressDialog progressDialog;
private Polling activity;
private int id = -1;
private JSONParser jsonParser;
private static String loginURL = "http://davidjkelley.net/android_api/";
private static String registerURL = "http://davidjkelley.net/android_api/";
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";
TextView loginErrorMsg = (EditText)activity.findViewById(R.id.loginErrorMsg);
EditText userName = (EditText)activity.findViewById(R.id.emailEditText);
EditText passwordEdit = (EditText)activity.findViewById(R.id.passEditText);
public LoginTask(Polling activity, ProgressDialog progressDialog)
{
this.activity = activity;
this.progressDialog = progressDialog;
}
所以我想在LoginTask的构造函数中添加第三个参数,本质上是我的LoginFragment的一个实例。我的目标是更新TextView或在屏幕上显示Toast以澄清登录是成功还是失败:现在,用户无法告知登录是如何进行的。想法?
答案 0 :(得分:4)
好奇地说你不想传递碎片(它们与活动的“链接”是一个上下文并且传递上下文是baaad)
您希望传递一个小对象,可以帮助您从任务回调到片段。
我也会使用界面。这是我的例子:
片段:
public class LoginFragment extends Fragment implements OnClickListener, OnLoginListener{
Button loginButton;
TextView loginErrorMsg;
private ProgressDialog progressDialog;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Logging in...");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_login, container, false);
loginButton = v.findViewById(R.id.button);
loginButton.setOnClickListener(this);
return v;
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
Log.v("LoginF", "onclick");
progressDialog.show();
LoginTask loginTask = new LoginTask(this);
loginTask.execute();
break;
default:
break;
}
}
@Override
public void onLoginSuccess() {
progressDialog.dismiss();
// Yayy
}
@Override
public void onLoginFailure() {
progressDialog.dismiss();
// Boo
}
}
ASyncTask:
public class LoginTask extends AsyncTask<String, Void, Integer> {
private final OnLoginListener listener;
public interface OnLoginListener{
public void onLoginSuccess();
public void onLoginFailure();
}
public LoginTask(OnLoginListener listener) {
this.listener = listener;
}
@Override
protected Integer doInBackground(String... params) {
try{
// Something
} catch (SomeException e){
listener.onLoginFailure();
}
return null;
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
listener.onLoginSuccess();
}
}
如果您了解界面,您的世界将会开放,您的代码将看起来不像亚马逊丛林,更像是一个组织良好的花园; - )
答案 1 :(得分:1)
我建议您使用Callback接口来实现此目的。将特定于UI的(实际上是特定于上下文的)对象传递给AsyncTask通常不是一个好主意。
这是我的建议。使用这种方法,您甚至不需要传递Fragment
左右。
免责声明:我实际上没有尝试过运行此代码 - 只需将其输入我的脑海。所以它甚至可能无法编译 - 它只是作为指南。
interface LoginCallback{
void onLoginSuccess();
void onLoginFailure();
}
//onCreate code
TextView loginErrorMsg = (EditText)activity.findViewById(R.id.loginErrorMsg);
EditText userName = (EditText)activity.findViewById(R.id.emailEditText);
EditText passwordEdit = (EditText)activity.findViewById(R.id.passEditText);
LoginTask loginTask = new LoginTask(new LoginCallback(){
@Override
protected void onLoginSuccess(){
//Update UI
}
@Override
protected void onLoginFailure(){
//Update UI
}
});
loginTask.execute();
//LoginTask code.
public class LoginTask extends AsyncTask<String, Void, Integer> {
LoginCallback callback;
ProgressDialog progressDialog;
public LoginTask(LoginCallback callback){
this.callback = callback;
@Override protected void onPreExecute(){
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Logging in...");
}
@Override
protected Integer doInBackground(String... params){
//Do you login logic here.
}
@Override
protected void onPostExecute(Integer result) {
progressDialog.dismiss();
if(loginSuccess){
callback.onLoginSuccess();
} else {
callback.onLoginFailure();
}
}
}
}