3

Я хочу использовать возвращаемое значение из класса 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); 
} 

} 

Пожалуйста, помогите мне:

ответ

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

Спасибо большое, сэр ........ вы решаете мою большую проблему. n сохранить мой день :) –

+1

Рад, что я смог вам помочь;) Счастливое кодирование! – 2Dee

+1

@ 2Dee Rocks. Превосходное кодирование –

1

Вы проблема, потому что вы прошли контекст активности в JSONParseAsync и внутри его конструктора вы бросаете его деятельности AppCompatActivity следующая деятельность произнесения к вашему OnTaskCompleteListener .. Так что, ваша деятельность должна внедрять слушателя, а не ваш фрагмент.

просто позвольте HomeActivity реализовать свой интерфейс OnTaskCompleteListener.

Пример:

public class HomeActivity extends AppCompatActivity implements OnTaskCompleteListener{ 
... 
} 

На мой взгляд, не создавать свои собственные классы до тех пор пока его не требуется. В вашем случае вы также должны были выполнить свою задачу с анонимным классом. Нет необходимости создавать отдельный класс.

Надеюсь, вы поняли мою точку зрения.

Тем не менее, то, что вы можете сделать это, передать контекст и OnTaskCompleteListener в конструкторе

private void loadProfileAction() { 
... 

     JSONParseAsync parseAsync = new JSONParseAsync(getContext(), this); // also try getActivity() 
     ... 

} 

и изменить конструктор:

public JSONParseAsync(Context context, OnTaskCompleteListener listener){ 
    this.mContext = context; 
    this.mCallback = listener; 
} 
+0

но у меня нет требования там ..... –

+0

@ Garg's Тогда, почему вы создали интерфейс? –

+0

b'coz Мне нужно вызвать класс JSONParseAsync многократно в проекте, поэтому нужен результат возврата json. –

2

Используйте 2 Параметры для задач конструктора:

public JSONParseAsync(Context context, OnTaskCompleteListener listener){ 
    this.mContext = context; 
    this.mCallback = listener; 
} 

и создать новый экземпляр с помощью

JSONParseAsync parseAsync = new JSONParseAsync(getContext(), this); 

Потому что, когда вы передаете контекст, вы не передаете фрагмент, но основную деятельность. Таким образом, вам понадобится 2 параметра, если вы хотите использовать свою задачу внутри своего фрагмента.

+0

спасибо, что помогли мне ..... ваши анны также попали –

Смежные вопросы