将侦听器传递给异步任务时出现类转换错误

时间:2014-02-18 11:45:10

标签: java android class asynchronous

我正在处理异步任务,结构是主类中的实现接口,将主类作为侦听器传递给异步任务,当异步类完成时,调用监听器函数,问题是当我通过async任务的主类它返回以下错误:

02-18 19:37:43.826: E/AndroidRuntime(15928): FATAL EXCEPTION: AsyncTask #2
02-18 19:37:43.826: E/AndroidRuntime(15928): java.lang.RuntimeException: An error occured while executing doInBackground()
02-18 19:37:43.826: E/AndroidRuntime(15928):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.lang.Thread.run(Thread.java:856)
02-18 19:37:43.826: E/AndroidRuntime(15928): Caused by: java.lang.ClassCastException: com.project.hkseven.Fragment.Home$1 cannot be cast to com.project.hkseven.Listener.LoginListener
02-18 19:37:43.826: E/AndroidRuntime(15928):    at com.project.hkseven.Utility.APIHandler.doInBackground(APIHandler.java:69)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at com.project.hkseven.Utility.APIHandler.doInBackground(APIHandler.java:1)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-18 19:37:43.826: E/AndroidRuntime(15928):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-18 19:37:43.826: E/AndroidRuntime(15928):    ... 5 more

以下是我如何调用主要类(片段)并将其传递给异步任务

new APIHandler(getActivity(),tracker,"login").execute(this,session.getAccessToken());

API处理程序是一个异步任务,处理方式如下

public class APIHandler extends AsyncTask<Object, Void, JSONObject> {
    private String TAG = "APIHandler";
    private LoginListener loginListener;
    private UploadImageListener uploadImageListener;
    private UpdateProfileListener updateProfileListener;
    private MyPtListener myPtListener;

    public Context ctx;
    public String type;
    public String url;
    public String formType;
    public EasyTracker tracker;
    public String token;
    public String memId;

    public APIHandler(Context _ctx,EasyTracker _tracker,String _formType) {
        this.ctx = _ctx;
        this.tracker = _tracker;
        this.formType = _formType;

        //Get access data
        SharedPreferences prefs = ctx.getSharedPreferences("userInfo", 0);
        token = prefs.getString("token","");
        memId = prefs.getString("memId","");
    }

    @Override
    protected JSONObject doInBackground(Object... params) {

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        if (formType.equals("login")){

            url = Constant.loginAPI;
            loginListener = (LoginListener) params[0];

            Log.d(TAG, "Login API(token): " + params[1] );

            builder.addTextBody("var1", (String) params[1]); //Facebook access token
            builder.addTextBody("var2", "2"); //Device type 2 = android

.......................

@Override
    protected void onPostExecute(JSONObject result) {


        try {
            if(result != null)  {
                if (formType.equals("login")){
                    if (result.getString("result").equals("ok")) {
                        loginListener.onLoginComplete(result.getString("member_id"),result.getString("token"));
                    }else {
                        loginListener.onLoginFailure(result.getString("error_code"));   
                    }

更新

感谢您的回复,我已经实现了loginListener,但它仍然会出错。

界面:

public interface LoginListener {
    public void onLoginComplete(String memberId, String token);
    public void onLoginFailure(String errorMsg);
}

Home类片段:

public class Home extends Fragment implements LoginListener {
    public View rootView;
    public ImageView HomeBg;
    public ImageView buttonLoginLogout;
    public TextView chi;
    public TextView eng;
    public ColorStateList oldColor;
    public SharedPreferences prefs;
    public EasyTracker tracker = null;
    public String[] PERMISSION_ARRAY_READ = {"email"};
    public List<String> PERMISSION_LIST;
    public SharedPreferences.Editor editor;
    public ProgressDialog pd;

    //Facebook login
    private Session.StatusCallback statusCallback = new SessionStatusCallback();

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

        tracker = EasyTracker.getInstance(getActivity());

        PERMISSION_LIST = Arrays.asList(PERMISSION_ARRAY_READ);

        prefs = getActivity().getSharedPreferences("userInfo", 0);
        editor = prefs.edit();

        getActivity().getActionBar().hide();

        rootView = inflater.inflate(R.layout.home, container, false);
        buttonLoginLogout = (ImageView) rootView.findViewById(R.id.home_connectFB);
        eng = (TextView) rootView.findViewById(R.id.btn_eng);
        chi = (TextView) rootView.findViewById(R.id.btn_chi);

        if (Utility.getLocale(getActivity()).equals("TC")) {
            chi.setTextColor(getActivity().getResources().getColor(
                    android.R.color.white));
            oldColor = eng.getTextColors();
        } else {
            eng.setTextColor(getActivity().getResources().getColor(
                    android.R.color.white));
            oldColor = chi.getTextColors();

        }

        eng.setOnClickListener(setChangeLangListener("EN"));
        chi.setOnClickListener(setChangeLangListener("TC"));

        //Facebook login
        Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);

        Session session = Session.getActiveSession();
        if (session == null) {
            if (savedInstanceState != null) {
                session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState);
            }
            if (session == null) {
                session = new Session(getActivity());
            }
            Session.setActiveSession(session);
            if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
                session.openForRead(new Session.OpenRequest(this).setPermissions(PERMISSION_LIST).setCallback(statusCallback));
            }
        }

       updateView();
       return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        Session.getActiveSession().addCallback(statusCallback);
        tracker.set(Fields.SCREEN_NAME, "hk7app/CX/" + Utility.getLocale(getActivity()) + "/Landing Page");
        tracker.send(MapBuilder.createAppView().build());
    }

    @Override
    public void onStop() {
        super.onStop();
        Session.getActiveSession().removeCallback(statusCallback);
        EasyTracker.getInstance(getActivity()).activityStop(getActivity());
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Session session = Session.getActiveSession();
        Session.saveSession(session, outState);
    }

    @SuppressWarnings("deprecation")
    private void updateView() {
        final Session session = Session.getActiveSession();
        if (session.isOpened()) {
            Request.executeMeRequestAsync(session,
                new Request.GraphUserCallback() {
                    @Override
                    public void onCompleted(GraphUser user,Response response) {
                        // TODO Auto-generated method stub
                        if (user != null) {
                            if (!user.getId().equals(prefs.getString("fbId",""))) {
                                editor.putString("fbId", user.getId());
                                editor.putString("fName", user.getFirstName());
                                editor.putString("lName", user.getLastName());
                                editor.putString("email", user.asMap().get("email").toString());
                                editor.commit();
                                //pd = ProgressDialog.show(getActivity(), getActivity().getResources().getString(R.string.sys_info),getActivity().getResources().getString(R.string.loading));
                                Log.d("test1",session.getAccessToken());
                                new APIHandler(getActivity(),tracker,"login").execute(this,session.getAccessToken());
                            } else {
                                onLoginComplete("","");
                            }
                        }
                    }
            });             

        } else {
            buttonLoginLogout.setImageResource(R.drawable.landing_btn_connect_facebook);
            buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) { onClickLogin(); }
            });
        }
    }

    private void onClickLogin() {
        tracker.send(MapBuilder.createEvent("menu_click","Fbconnect","connectFB_" + Utility.getLocale(getActivity()),null).build());
        Session session = Session.getActiveSession();
        if (!session.isOpened() && !session.isClosed()) {
            session.openForRead(new Session.OpenRequest(this).setPermissions(PERMISSION_LIST).setCallback(statusCallback));
        } else {
            Session.openActiveSession(getActivity(), this, true, statusCallback);
        }
    }

    private class SessionStatusCallback implements Session.StatusCallback {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            updateView();
        }
    }

    public OnClickListener setChangeLangListener(final String lang) {
        OnClickListener changeLangListener = new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Configuration config = new Configuration(getResources().getConfiguration());

                if (Utility.getLocale(getActivity()).equals("TC") && lang.equals("EN")) {
                    tracker.send(MapBuilder.createEvent("menu_click","language", "switchEN", null).build());
                    config.locale = Locale.ENGLISH;
                    chi.setTextColor(oldColor);
                    eng.setTextColor(getActivity().getResources().getColor(
                            android.R.color.white));
                } else if (Utility.getLocale(getActivity()).equals("EN") && lang.equals("TC")) {
                    tracker.send(MapBuilder.createEvent("menu_click","language", "switchTC", null).build());
                    config.locale = Locale.TRADITIONAL_CHINESE;
                    eng.setTextColor(oldColor);
                    chi.setTextColor(getActivity().getResources().getColor(
                            android.R.color.white));
                }

                getResources().updateConfiguration(config,getResources().getDisplayMetrics());

                onConfigurationChanged(config);
            }
        };
        return changeLangListener;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
      super.onConfigurationChanged(newConfig);
      Intent intent = getActivity().getIntent();
      intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
      getActivity().finish();
      startActivity(intent);
    }

    @Override
    public void onResume() {
        super.onResume();
        AppEventsLogger.activateApp(getActivity(),getResources().getString(R.string.app_id));
    }

    @Override
    public void onLoginComplete(String memberId, String token) {    
        if (pd != null)
            pd.dismiss();

        if (!memberId.equals("") && !token.equals("")) {
            editor.putString("memId", memberId);
            editor.putString("token", token);
        }

        buttonLoginLogout.setImageResource(R.drawable.landing_btn_take_a_selfie);
        buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                 tracker.send(MapBuilder.createEvent("menu_click","TakeSelfie","Selfie_now_" + Utility.getLocale(getActivity()),null).build());
                ((LandingPage)getActivity()).tabHost.setCurrentTab(2);
            }
        });
    }

    @Override
    public void onLoginFailure(String errorMsg) {
        if (pd != null)
            pd.dismiss();

        Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_LONG).show();
    }

}

更新(2):

我没有将Home转换为LoginListener,而是试图简单地不将其强制转换,问题是它仍然抛出异常

Caused by: java.lang.ClassCastException: com.project.hkseven.Fragment.Home$1 cannot be cast to com.project.hkseven.Fragment.Home

4 个答案:

答案 0 :(得分:2)

我想这个问题就在于这一行,

loginListener = (LoginListener) params[0];

因为你的params [0]是这个,我指的是Home。但是,在doInBackground()方法中,您已将其转换为LoginListener。所以@Blackbelt说,你能检查一下你的Home是否实现了LoginListener。

答案 1 :(得分:1)

可以解决您的问题的方法是替换此行

loginListener = (LoginListener) params[0];

通过

  TheActivityThatYoupassedin= (TheActivityThatYoupassedin) params[0];
        if(TheActivityThatYoupassedin instanceOf LoginListener){


    }
else{
throw new ClassCastException("Home does not implements the loginlistener);
}

答案 2 :(得分:0)

据我了解,您使用的接口LoginListener作为CallBack侦听器。但是,不幸的是,您没有在LoginListener课程中实现Home界面。你可以查看你的班级定义......

public class Home extends Fragment implements LoginListener {

答案 3 :(得分:0)

在onCreate而不是onCreateView中获取上下文修复了问题。谢谢你的帮助