Java 使用从JSON加载的图像滚动ListView时出现NullPointerException

Java 使用从JSON加载的图像滚动ListView时出现NullPointerException,java,android,json,listview,nullpointerexception,Java,Android,Json,Listview,Nullpointerexception,我有一个错误,在Android中使用ListView时,它填充了图像。图像URL来自tumblr JSON,android query将加载它们。我得到的错误消息是: 12-12 21:55:38.032 4334-4334/com.example.tumblrviewer E/InputEventReceiver﹕ Exception dispatching input event. 12-12 21:55:38.040 4334-4334/com.example.tumblrvi

我有一个错误,在Android中使用ListView时,它填充了图像。图像URL来自tumblr JSON,android query将加载它们。我得到的错误消息是:

12-12 21:55:38.032    4334-4334/com.example.tumblrviewer E/InputEventReceiver﹕ Exception dispatching input event.
12-12 21:55:38.040    4334-4334/com.example.tumblrviewer D/dalvikvm﹕ GC_FOR_ALLOC freed 760K, 12% free 9993K/11292K, paused 5ms, total 6ms
12-12 21:55:38.040    4334-4334/com.example.tumblrviewer E/MessageQueue-JNI﹕ java.lang.NullPointerException
        at com.example.tumblrviewer.MenuArrayAdapter.getView(MenuArrayAdapter.java:76)
        at android.widget.AbsListView.obtainView(AbsListView.java:2161)
        at android.widget.ListView.makeAndAddView(ListView.java:1840)
        at android.widget.ListView.fillDown(ListView.java:675)
        at android.widget.ListView.fillGap(ListView.java:639)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4970)
        at android.widget.AbsListView.onGenericMotionEvent(AbsListView.java:3680)
        at android.view.View.dispatchGenericMotionEventInternal(View.java:7479)
        at android.view.View.dispatchGenericMotionEvent(View.java:7460)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchGenericMotionEvent(PhoneWindow.java:1974)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchGenericMotionEvent(PhoneWindow.java:1428)
        at android.app.Activity.dispatchGenericMotionEvent(Activity.java:2460)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchGenericMotionEvent(PhoneWindow.java:1928)
        at android.view.View.dispatchPointerEvent(View.java:7566)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:132)
        at android.os.Looper.loop(Looper.java:124)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
12-12 21:55:38.044    4334-4334/com.example.tumblrviewer D/AndroidRuntime﹕ Shutting down VM
12-12 21:55:38.044    4334-4334/com.example.tumblrviewer W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xa4bd3648)
12-12 21:55:38.052    4334-4334/com.example.tumblrviewer E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at com.example.tumblrviewer.MenuArrayAdapter.getView(MenuArrayAdapter.java:76)
        at android.widget.AbsListView.obtainView(AbsListView.java:2161)
        at android.widget.ListView.makeAndAddView(ListView.java:1840)
        at android.widget.ListView.fillDown(ListView.java:675)
        at android.widget.ListView.fillGap(ListView.java:639)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4970)
        at android.widget.AbsListView.onGenericMotionEvent(AbsListView.java:3680)
        at android.view.View.dispatchGenericMotionEventInternal(View.java:7479)
        at android.view.View.dispatchGenericMotionEvent(View.java:7460)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at android.view.ViewGroup.dispatchTransformedGenericPointerEvent(ViewGroup.java:1819)
        at android.view.ViewGroup.dispatchGenericPointerEvent(ViewGroup.java:1772)
        at android.view.View.dispatchGenericMotionEvent(View.java:7453)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchGenericMotionEvent(PhoneWindow.java:1974)
        at com.android.internal.policy.impl.PhoneWindow.superDispatchGenericMotionEvent(PhoneWindow.java:1428)
        at android.app.Activity.dispatchGenericMotionEvent(Activity.java:2460)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchGenericMotionEvent(PhoneWindow.java:1928)
        at android.view.View.dispatchPointerEvent(View.java:7566)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:132)
        at android.os.Looper.loop(Looper.java:124)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
它指向Menuarray适配器第76行,其中包含:

        mAQ.id(viewHolder.mImageView).image(item.photos[0].photoUrl.uri, false, false, 600, 0, null, Constants.FADE_IN);
我很确定这个对象不是空的,因为错误是随机发生的,每次ArrayAdapter中都有不同的项。它发生在我快速上下滚动ListView时。我看到图像没有时间加载。这可能与记忆问题有关吗?内存中的数据太多,应用程序崩溃?如果是这样,如果我想继续使用无限滚动,那么什么是一个好的解决方案?我不想在底部添加“加载更多”按钮,因为Instagram没有这样的按钮,它可以加载大量图像

该类的完整代码如下所示:

package com.example.tumblrviewer;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.androidquery.util.Constants;
import com.example.tumblrviewer.model.HomeResponse;
import com.example.tumblrviewer.model.Item;

import org.json.JSONException;
import org.json.JSONObject;


public class MenuArrayAdapter extends ArrayAdapter<Item> {

private final LayoutInflater mInflater;
private final int mResourceId;
private AQuery mAQ;
private int postOffset;
public MenuArrayAdapter(Context context, int resource) {
    super(context, resource);

    mInflater = LayoutInflater.from(context);
    mResourceId = resource;
    mAQ = new AQuery(context);
    postOffset=0;
   //loadImages(postOffset);
}


public void setPosts(Item[] posts) {

    //clear();

    for (Item item : posts) {

        add(item);
    }

    if (isEmpty()) {
        notifyDataSetInvalidated();
    } else {
        notifyDataSetChanged();
    }
}

@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {

    ViewHolder viewHolder = null;

    if (convertView == null) {

        viewHolder = new ViewHolder();
        convertView = mInflater.inflate(mResourceId, viewGroup, false);
        viewHolder.mImageView = (ImageView) convertView.findViewById(R.id.tumblr_photo_iv);
        //viewHolder.mTagsLayout=(LinearLayout) convertView.findViewById(R.id.tags_layout);
        convertView.setTag(viewHolder);
    } else {

        viewHolder = (ViewHolder) convertView.getTag();
    }

    Item item = getItem(i);

   //if ( item.photos[0].photoUrl.uri != null) {
        mAQ.id(viewHolder.mImageView).image(item.photos[0].photoUrl.uri, false, false, 600, 0,  null, Constants.FADE_IN);
   //}

    return convertView;


}


private class ViewHolder {
    ImageView mImageView;
    //LinearLayout mTagsLayout;

}
}
package com.example.tumblrviewer;
导入android.content.Context;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.ImageView;
导入com.androidquery.AQuery;
导入com.androidquery.callback.AjaxCallback;
导入com.androidquery.callback.AjaxStatus;
导入com.androidquery.util.Constants;
导入com.example.tumblrviewer.model.HomeResponse;
导入com.example.tumblrviewer.model.Item;
导入org.json.JSONException;
导入org.json.JSONObject;
公共类MenuArrayAdapter扩展了ArrayAdapter{
私人最终布局平面图;
私人最终int mResourceId;
私人水渠mAQ;
专用int postOffset;
公共菜单数组适配器(上下文,int资源){
超级(上下文、资源);
mInflater=LayoutInflater.from(上下文);
mResourceId=资源;
mAQ=新水道(上下文);
postOffset=0;
//加载图像(后偏移);
}
公共无效设置员额(项目[]员额){
//清除();
(项目:员额){
增加(项目);
}
if(isEmpty()){
notifyDataSetionValidated();
}否则{
notifyDataSetChanged();
}
}
@凌驾
公共视图getView(int i、视图转换视图、视图组视图组){
ViewHolder ViewHolder=null;
if(convertView==null){
viewHolder=新的viewHolder();
convertView=mInflater.inflate(mResourceId,viewGroup,false);
viewHolder.mImageView=(ImageView)convertView.findViewById(R.id.tumblr\u photo\u iv);
//viewHolder.mTagsLayout=(LinearLayout)convertView.findViewById(R.id.tags\u布局);
convertView.setTag(viewHolder);
}否则{
viewHolder=(viewHolder)convertView.getTag();
}
项目=获取项目(i);
//if(item.photos[0].photoUrl.uri!=null){
mAQ.id(viewHolder.mImageView).image(item.photos[0].photoUrl.uri,false,false,600,0,null,Constants.FADE_-IN);
//}
返回视图;
}
私有类视窗持有者{
图像视图;
//线性布局;
}
}
还有主要的活动

package com.example.tumblrviewer;

import android.app.Activity;
import android.os.Bundle;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.example.tumblrviewer.model.HomeResponse;

import org.json.JSONException;
import org.json.JSONObject;

public class WeHaveTheMunchiesActivity extends Activity {

private AQuery mAQ;
private TextView mResultTextView;
private ListView mListView;
private MenuArrayAdapter mItemArrayAdapter;
private int postOffset;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_viewer);
    mListView = (ListView) findViewById(R.id.items_lv);
    mAQ = new AQuery(this);
    mItemArrayAdapter = new MenuArrayAdapter(this, R.layout.item_on_list);
    mListView.setAdapter(mItemArrayAdapter);
    postOffset=0;
    loadImages(postOffset);



    mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {

        }

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {


            int lastItem = firstVisibleItem + visibleItemCount;
            if(lastItem == totalItemCount ){

                if(postOffset <= 10662
                        && mListView.getChildAt(mListView.getChildCount() - 1) != null
                        && mListView.getLastVisiblePosition() == mListView.getAdapter().getCount() - 1
                        && mListView.getChildAt(mListView.getChildCount() - 1).getBottom() <= mListView.getHeight()) {
                    Toast.makeText(getApplicationContext(), "Bottom!", Toast.LENGTH_LONG).show();
                    loadImages(postOffset);
                    System.out.println("postOffset "+postOffset);

                }
            }
        }
    });

}


private void loadImages(int offset) {

    String url = Constants.TUMBLR_API_BLOG_URL + Constants.TUMBLR_API_BLOG_HOSTNAME +
            Constants.TUMBLR_API_CONTENT_TYPE + Constants.TUMBLR_API_KEY_NAME +
            Constants.TUMBLR_API_KEY + "&offset=" + Integer.toString(offset);


    AjaxCallback<JSONObject> cb = new AjaxCallback<JSONObject>();
    cb.url(url).type(JSONObject.class).weakHandler(this, "itemsCallback");
    mAQ.ajax(cb);
    postOffset=postOffset+20;


}

public void itemsCallback(String url, JSONObject json, AjaxStatus status) throws JSONException {
    //Toast.makeText(getApplicationContext(), status.getRedirect(), Toast.LENGTH_LONG).show();
    //Toast.makeText(getApplicationContext(), status.getCode(), Toast.LENGTH_LONG).show();
    //mResultTextView.setText(status.getMessage());
    if (json != null) {
        HomeResponse homeResponse = HomeResponse.fromJsonObject(json.getJSONObject("response"));
        System.out.print(homeResponse.items);
        mItemArrayAdapter.setPosts(homeResponse.items);
    }

}


}
package com.example.tumblrviewer;
导入android.app.Activity;
导入android.os.Bundle;
导入android.widget.AbsListView;
导入android.widget.ListView;
导入android.widget.TextView;
导入android.widget.Toast;
导入com.androidquery.AQuery;
导入com.androidquery.callback.AjaxCallback;
导入com.androidquery.callback.AjaxStatus;
导入com.example.tumblrviewer.model.HomeResponse;
导入org.json.JSONException;
导入org.json.JSONObject;
公共类WehaveTheMunchies活动扩展活动{
私人水渠mAQ;
私有文本视图mResultTextView;
私有列表视图;
私人住宅;
专用int postOffset;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u list\u查看器);
mListView=(ListView)findViewById(R.id.items\u lv);
mAQ=新水道(本);
MiteMarrayaAdapter=新的MenuArrayAdapter(该,R.layout.item_在_列表中);
setAdapter(MiteMarrayaAdapter);
postOffset=0;
加载图像(后偏移);
mListView.setOnScrollListener(新的AbsListView.OnScrollListener(){
@凌驾
CrollStateChanged上的公共无效(AbsListView AbsListView,int i){
}
@凌驾
public void onScroll(AbsListView AbsListView、int firstVisibleItem、int visibleItemCount、int totalItemCount){
int lastItem=firstVisibleItem+visibleItemCount;
如果(lastItem==totalItemCount){

if(postOffset)可能是加载时出现问题的原因。如果使用AsyncTask加载Background中的图像呢?其中的某些内容绝对为空。可能是items、items.photos、items.photos[0],item.photos[0].photoUrl或maq.id的返回。使用if语句分别测试每一个,并找出它是第一个。这样我们可以更容易地帮助您,您也可以自己找出它。Gabe有它-您的数据在某个地方为空。另一种查找它的方法是输出整个JSON字符串。@Gabetechan您是对的,我已经排除了such可能性,因为之前我添加了测试,在测试中我检查了item.photos[0].photoUrl!=null,但结果是item.photos为null,因为JSON中的某些帖子没有照片。现在我正在过滤JSON输出,只选择照片帖子。非常感谢!