我想使用接口从AsyncTask
类返回一个值。问题是我的以下代码在Activity中工作正常但在片段类中没有。
我这样得ClassCastException
:
java.lang.ClassCastException: com.demo.HomeActivity cannot be cast to com.demo.helper.OnTaskCompleteListener
at com.demo.util.JSONParseAsync.<init>(JSONParseAsync.java:33)
at com.demo.fragment.PersonalDetailFragment.loadProfileAction(PersonalDetailFragment.java:93)
at com.demo.fragment.PersonalDetailFragment.onCreate(PersonalDetailFragment.java:81)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1942)
接口类:
public interface OnTaskCompleteListener {
void onTaskComplete(JSONObject jsonObject);
}
PersonalDetailFragment类:
public class PersonalDetailFragment extends Fragment implements OnTaskCompleteListener {
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_personal_detail, container,
false);
loadProfileAction();
return view;
}
private void loadProfileAction() {
SessionPreference preference = new SessionPreference(getActivity());
try {
String encodedUrl = URLEncoder.encode(preference.getSessionId(), "UTF-8")
+ ","
+ URLEncoder.encode(Constants.URL_TOKEN, "UTF-8");
// URL base64Encode
String processUrl = Base64.encodeToString(encodedUrl.getBytes("UTF-8"), Base64.DEFAULT);
JSONParseAsync parseAsync = new JSONParseAsync(getContext()); // also try getActivity()
parseAsync.execute((URLConstants.GET_USER_DETAIL_URL+processUrl).trim());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onTaskComplete(JSONObject jsonObject) {
try {
boolean status = jsonObject.getBoolean(URLConstants.TAG_STATUS);
Log.e(Constants.DEBUG_TAG, "Status:- " + status);
if (status == true) {
JSONArray dataarray = jsonObject.getJSONArray(URLConstants.TAG_DATA);
JSONObject data = dataarray.getJSONObject(0);
fillProfileData(data);
} else if (status == false) {
Snackbar.make(view,
"Incorrect User Name OR Password",
Snackbar.LENGTH_LONG).show();
}
Log.i("GARG", "Excution Line Finish ");
} catch (Exception e) {
e.printStackTrace();
}
}
JSONParseAsync类:
public class JSONParseAsync extends AsyncTask<String, String, JSONObject>{
private Context mContext;
ProgressDialog mProgress;
private OnTaskCompleteListener mCallback;
public JSONParseAsync(Context context){
this.mContext = (AppCompatActivity)context;
this.mCallback = (OnTaskCompleteListener) mContext;
}
@Override
protected JSONObject doInBackground(String... URL) {
JSONObject jsonObj = null;
try{
Log.d(Constants.DEBUG_TAG, "line excucation 2 doInBackground");
ServiceHandler sh = new ServiceHandler();
String url = URL[0];
Log.d(Constants.ACTIVITY_TAG, "...." + url);
// Making a request to url and getting response.
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d(Constants.JSON_TAG, "" + jsonStr);
if (jsonStr != null) {
jsonObj = new JSONObject(jsonStr);
Log.e(Constants.JSON_TAG, "" + jsonObj);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonObj;
}
@Override
protected void onPreExecute() {
Log.d(Constants.DEBUG_TAG, "line excucation 1 onPreexcute");
mProgress = new ProgressDialog(mContext);
mProgress.setMessage("Downloading nPlease wait...");
mProgress.show();
}
@Override
protected void onProgressUpdate(String... values) {
Log.d(Constants.DEBUG_TAG, "line excucation 3 onProgressUpdate");
mProgress.setMessage(values[0]);
}
@Override
protected void onPostExecute(JSONObject result) {
Log.d(Constants.DEBUG_TAG, "line excucation 3 onPostExecute");
mProgress.dismiss();
//This is where you return data back to caller
Log.d(Constants.APP_TAG, " final result:- "+result);
mCallback.onTaskComplete(result);
}
}
请帮帮我:
答案 0 :(得分:3)
通过这样做
JSONParseAsync parseAsync = new JSONParseAsync(getContext());
您已将Activity
发送到AsyncTask
,但实施Fragment
的是OnTaskCompleteListener
。
要么Activity
实施您的界面,或
这样做:
JSONParseAsync parseAsync = new JSONParseAsync(this, getContext());
并将您的AsyncTask
构造函数更改为
public JSONParseAsync(OnTaskCompleteListener listener, Context context){
this.mContext = context;
//this.mContext = (AppCompatActivity)context; -> you don't need that cast, AppCompatActivity is a subclass of Context
this.mCallback = listener;
}
答案 1 :(得分:2)
为任务构造函数使用2个参数:
public JSONParseAsync(Context context, OnTaskCompleteListener listener){
this.mContext = context;
this.mCallback = listener;
}
并使用
创建一个新实例 JSONParseAsync parseAsync = new JSONParseAsync(getContext(), this);
因为当您传递Context时,您不会传递片段而是传递基础活动。因此,如果您想在片段中使用任务,那么您可能需要2个参数。
答案 2 :(得分:1)
您的问题是,因为您已将活动上下文传递给ul
,并且在其构造函数内部,您将其投射到活动JSONParseAsync
,然后将活动投射到您的AppCompatActivity
..所以,你的活动应该是实现监听器,而不是你的片段。
让OnTaskCompleteListener
实现您的界面HomeActivity
。
示例:强>
OnTaskCompleteListener
在我看来,除非并且直到需要,否则不要创建自定义类。在你的情况下你也应该用匿名类来完成你的任务..没有必要创建单独的类..
我希望你明白我的观点。
但是,你可以做的是,在构造函数中传递上下文和OnTaskCompleteListener
public class HomeActivity extends AppCompatActivity implements OnTaskCompleteListener{
...
}
并将构造函数更改为:
private void loadProfileAction() {
...
JSONParseAsync parseAsync = new JSONParseAsync(getContext(), this); // also try getActivity()
...
}