Android - 接口callBack抛出空指针异常

Posted

技术标签:

【中文标题】Android - 接口callBack抛出空指针异常【英文标题】:Android - Interface callBack throws null pointer Exception 【发布时间】:2014-06-12 22:41:36 【问题描述】:

我的所有活动/片段等都有一个异步任务,但现在我正在为每个活动实现一个接口,但我的接口 callBack 始终为空,我不知道为什么。每次调用 asyncTask 的 Activity 都实现了接口。

实现接口并调用的我的类是 asyncTask

public class MainActivity extends Activity implements MainActivityAsyncInterface, OnClickListener, UserPictureDialogInterface 

private DrawerLayout            moodydrawerLayout;

private HashMap<String, String> organizedCourses    = new HashMap<String, String>();

// ManSession Manager Class
ManSession                      session;

private long                    startTime;
private long                    endTime;
private ModDevice               md;

private float                   screenX;

private float                   screenY;

private int                     shotType            = ShowcaseView.TYPE_ONE_SHOT;

private MoodleUser              currentUser;

private String                  url;

private String                  token;

private String                  userId;

private static long             backPressed;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    // The following line triggers the initialization of ACRA
.......

    session = new ManSession(getApplicationContext());
    url = session.getValues(ModConstants.KEY_URL, null);
    token = session.getValues(ModConstants.KEY_TOKEN, null);
    userId = session.getValues(ModConstants.KEY_ID, null);

    new DataAsyncTask(this,).execute(url, token, EXAMPLE.CORE_USER_GET_USERS_BY_ID, userId, MainActivity.class.getSimpleName());

    populateLeft();
    populateRight();
    receiveNotification();
    initDemoOverlay();
    drawerLayoutListener();
    warningMessage(checkConnection(), Toast.LENGTH_LONG, null, getString(R.string.no_internet));

    ChangeLogListView sad = new ChangeLogListView(getApplicationContext());


异步任务

public class DataAsyncTask extends AsyncTask<Object, Void, Object> 
Object                              jObj    = null;
public MainActivityAsyncInterface   mainActivityInterface;
private ProgressDialog              dialog;
private CountDownTimer              cvt     = createCountDownTimer();
private Context                     context;
private MoodleServices              webService;
private String                      parentActivity;
private String                      fillTheSpace;

public DataAsyncTask(Context context) 
    this.context = context;
    dialog = new ProgressDialog(context);


@Override
protected void onPreExecute() 
    super.onPreExecute();
    cvt.start();


@Override
protected Object doInBackground(Object... params) 
    String urlString = (String) params[0];
    String token = (String) params[1];
    webService = (MoodleServices) params[2];
    Object webServiceParams = params[3];
    parentActivity = (String) params[4];

        case EXAMPLE:
            InputStream inputStream = new URL(urlString).openStream();
            Drawable drawable = Drawable.createFromStream(inputStream, null);
            inputStream.close();
            return drawable;

        default:
            return null;

        
     catch (Exception e) 
        e.printStackTrace();
    
    return null;


/**
 * <p>
 * Method that parses a supposed id list object
 * </p>
 *
 * @param Object
 *            ids - The object to be parsed to Long[].
 * @return resultList - The ids List
 */
private Long[] parseIds(Object ids) 

    Long[] resultList = null;

    try 
        resultList = (Long[]) ids;
     catch (Exception e) 
        resultList = new Long[1];

        resultList[0] = (Long) ids;
    

    return resultList;


@Override
protected void onPostExecute(Object obj) 
    cvt.cancel();

    if (dialog != null && dialog.isShowing())   
        dialog.dismiss();

    switch (webService) 
    case EXAMPLE:
        if (parentActivity.equalsIgnoreCase(MainActivity.class.getSimpleName()))
            mainActivityInterface.userAsyncTaskResult(obj); \\This the line 173 and the obj != null and mainActivityInterface is null

        if (parentActivity.equalsIgnoreCase(UserDetailsActivity.class.getSimpleName()))
            fillTheSpace = "TODO - Interface for each parent class";

        if (parentActivity.equalsIgnoreCase(FragTopicsPreview.class.getSimpleName()))
            fillTheSpace = "TODO - Interface for each parent class";

        if (parentActivity.equalsIgnoreCase(FragTopics.class.getSimpleName()))
            fillTheSpace = "TODO - Interface for each parent class";
        break;

    case EXAMPLE2:
        if (parentActivity.equalsIgnoreCase(MainActivity.class.getSimpleName()))
            mainActivityInterface.userAsyncTaskResult(obj);

        if (parentActivity.equalsIgnoreCase(UserDetailsActivity.class.getSimpleName()))
            fillTheSpace = "TODO - Interface for each parent class";

        if (parentActivity.equalsIgnoreCase(FragTopicsPreview.class.getSimpleName()))
            fillTheSpace = "TODO - Interface for each parent class";

        if (parentActivity.equalsIgnoreCase(FragTopics.class.getSimpleName()))
            fillTheSpace = "TODO - Interface for each parent class";
        break;

    default:
        break;
    


private CountDownTimer createCountDownTimer() 
    return new CountDownTimer(250, 10) 
        @Override
        public void onTick(long millisUntilFinished) 

        

        @Override
        public void onFinish() 
            dialog = new ProgressDialog(context);
            dialog.setMessage("Loading...");
            dialog.setCancelable(false);
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();
        
    ;

Logcat:

04-27 11:54:11.520: E/androidRuntime(1428): FATAL EXCEPTION: main
04-27 11:54:11.520: E/AndroidRuntime(1428): Process: com.firetrap.moody, PID: 1428
04-27 11:54:11.520: E/AndroidRuntime(1428): java.lang.NullPointerException
04-27 11:54:11.520: E/AndroidRuntime(1428):     at connections.DataAsyncTask.onPostExecute(DataAsyncTask.java:173)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at android.os.AsyncTask.finish(AsyncTask.java:632)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at android.os.AsyncTask.access(AsyncTask.java:177)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at android.os.Handler.dispatchMessage(Handler.java:102)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at android.os.Looper.loop(Looper.java:136)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at android.app.ActivityThread.main(ActivityThread.java:5017)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at java.lang.reflect.Method.invokeNative(Native Method)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at java.lang.reflect.Method.invoke(Method.java:515)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-27 11:54:11.520: E/AndroidRuntime(1428):     at dalvik.system.NativeStart.main(Native Method)

根据我的经验,接口不应该使用我的代码发送 nullPointer 异常,并且不需要初始化接口,但此时我将所有选项都放在了桌面上。

【问题讨论】:

onPostExecute(DataAsyncTask.java:173) 是哪一行? 我对标记该行的代码发表了评论:mainActivityInterface.userAsyncTaskResult(obj); \\这是第 173 行,obj != null 和 mainActivityInterface 为 null 你没有初始化mainActivityInterface,如果你在哪里呢? 您从未将mainActivityInterface 设置为一个值,因此它为空。 一个值?! mainActivityInterface 是一个接口,你是不是建议初始化一个接口?!像 mainActivityInterface = toSomething? 【参考方案1】:

这是因为您从未将侦听器传递给您的任务。

您只在 constrctuor 中发送您的上下文,但它应该如下所示:

public DataAsyncTask(Context context , MainActivityAsyncInterface mainActivityInterface) 
    this.context = context;
    this.mainActivityInterface = mainActivityInterface;
    dialog = new ProgressDialog(context);

在您的活动中,将此添加到您开始任务的位置。

  YourAcivity.this. 

更新: 回答你的问题,

您可以创建 BaseActivity 来扩展 Activity 并实现您的监听器。 然后,您的所有活动都必须覆盖侦听器函数。

【讨论】:

我已经看到了这种可能性,但问题是每个活动的每个接口都有超过 6 个接口,所以唯一的解决方案是有 6 个构造函数,接口是否具有泛型类型? 你必须首先明白,你不能使用监听器,除非你在某个地方初始化它。 @firetrap 您似乎只使用了界面中的userAsyncTaskResult 方法。它应该是定义该方法的接口。 你可以创建BaseActivity扩展Activity并实现你的监听器,然后你所有的Activity都会扩展这个类。 没关系,异步任务类无权访问您的活动,除非发送您的监听器,即 YourAcivity.this。【参考方案2】:

如果MainActivityAsyncInterface 是您的活动实现的接口,您需要将其传递给您的异步任务。目前mainActivityInterface 从未初始化并且始终为空,因此您会遇到异常。

您可以在构造函数中传递引用

public DataAsyncTask(Context context, MainActivityAsyncInterface mainActivityInterface) 
    this.context = context;
    this.mainActivityInterface = mainActivityInterface;
    dialog = new ProgressDialog(context);

【讨论】:

以上是关于Android - 接口callBack抛出空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

android.R.id.home 抛出空指针异常

JSONObject 创建抛出空指针异常

SearchView 展开抛出空指针异常

赋值操作期间未抛出空指针异常

HashCode 抛出空指针异常

为啥非空列表会抛出空指针异常?