0

我已经从本教程成功地为 EndlessList 创建了一个演示。现在我想在我的项目中使用这个 EndlessList 来处理实时网络数据,我修改了下面的演示代码,

MainActivity.java

public class MainActivity extends Activity implements EndlessListView.EndlessListener,OnDismissListener
{
    EndlessListView lv;
    int mult = 1; 
    List<String> data;

    private ProgressDialog pd; 

    static final String KEY_ITEM = "item";
    static final String KEY_TITLE = "title";
    static final String KEY_DESCRIPTION = "description";
    static final String KEY_LINK = "link";
    static final String KEY_AUTHOR = "author";
    static final String KEY_GUID = "guid";

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override 
    public void onStart() 
    {
        super.onStart(); 
        lv = (EndlessListView) findViewById( R.id.listView );
    }

    @Override 
    public void onResume()
    {
        super.onResume();
        EndlessAdapter adp = new EndlessAdapter ( this, getXMLList(), R.layout.row_layout );
        lv.setAdapter(adp);
        lv.setListener(this);
        pd = new ProgressDialog(this);
        pd.setTitle( "Loading" );
        pd.setMessage( "Please wait" );
        pd.setIndeterminate(true);
        pd.setCancelable(false);
        pd.setOnDismissListener(this);
    }

    private class FakeLoader extends AsyncTask<String, Void, List<String> >
    {
        @Override 
        protected void onPreExecute() 
        {
            if ( pd != null )
            {
                pd.show();
            }
        }

        @Override 
        protected List<String> doInBackground ( String...params )
        {
            return getXMLList();
        }

        @Override 
        protected void onPostExecute ( List<String> result )
        {
            if ( pd != null ) 
            {
                pd.dismiss();
            }
            data = result;
        }
    }

    private List<String> getXMLList()
    {
        try
        {
            XMLParser parser = new XMLParser();
            String xml = parser.getXMLFromUrl( "http://www.vogella.com/article.rss" );
            Document doc = parser.getDomElement(xml);

            NodeList nl = doc.getElementsByTagName( KEY_ITEM );

            data = new ArrayList<String>();

            for ( int i = 0 ; i < nl.getLength() ; i++ )
            {
                Element el = (Element) nl.item( i );
                data.add( parser.getValue( el, KEY_LINK ) );
            }
        }
        catch ( Exception e ) { System.out.println ( "Error : " + e.toString() ); }

        return data;
    }

    @Override
    public void loadData() 
    {
        mult += 10; 
        FakeLoader fl = new FakeLoader(); 
        fl.execute(new String[]{});
    }

    @Override
    public void onDismiss(DialogInterface arg0) 
    {
        lv.addNewData(data);
    }
}

EndlessAdapter.java

public class EndlessAdapter extends ArrayAdapter<String> 
{
    private List<String> itemList;
    private Context context; 
    private int layoutId;

    public EndlessAdapter ( Context context, List<String> itemList, int layoutId )
    {
        super ( context, layoutId,itemList );
        this.itemList = itemList; 
        this.context = context;
        this.layoutId = layoutId;
    }

    @Override 
    public int getCount() 
    {
        return itemList.size();
    }

    @Override
    public String getItem ( int position )
    {
        return itemList.get(position);
    }

    @Override
    public long getItemId ( int position )
    {
        return itemList.get(position).hashCode();
    }

    @Override 
    public View getView ( int position, View convertView, ViewGroup parent )
    {
        View result = convertView;

        if ( result == null )
        {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            result = inflater.inflate( layoutId, parent, false );
        }

        TextView txtView = (TextView) result.findViewById( R.id.txtItem );
        txtView.setText( itemList.get(position) );

        return result;
    }
}

EndlessListView.java

public class EndlessListView extends ListView implements OnScrollListener 
{
    private boolean isLoading; 
    private EndlessListener listener; 
    private EndlessAdapter adapter;


    public EndlessListView ( Context context, AttributeSet attrs, int defStyle )
    {
        super( context, attrs, defStyle );
        this.setOnScrollListener(this);
    }

    public EndlessListView ( Context context, AttributeSet attrs )
    {
        super ( context, attrs ); 
        this.setOnScrollListener(this);
    }

    public EndlessListView ( Context context )
    {
        super ( context ); 
        this.setOnScrollListener(this);
    }

    public void setListener ( EndlessListener listener )
    {
        this.listener = listener;
    }

    @Override 
    public void onScroll( AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount )
    {
        if ( getAdapter() == null )
        {
            return; 
        }

        if ( getAdapter().getCount() == 0 )
        {
            return; 
        }

//      int l = visibleItemCount + firstVisibleItem;
//      
//      if ( l >= totalItemCount && !isLoading )
//      {
//          isLoading = true;
//          listener.loadData();
//      }

        boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount; 

        if ( loadMore && !isLoading )
        {
            isLoading = true;
            listener.loadData();
        }
    }

    @Override 
    public void onScrollStateChanged ( AbsListView view, int scrollState ) {} 

    public void setAdapter ( EndlessAdapter adapter )
    {
        super.setAdapter(adapter);
        this.adapter = adapter; 
    }


    public void addNewData ( List<String> data )
    {
        isLoading = false;
        adapter.addAll(data);
        adapter.notifyDataSetChanged();
    }

    public EndlessListener setListener() 
    { 
        return listener;
    }

    public static interface EndlessListener
    {
        public void loadData(); 
    }
}

但是当我运行上面的代码时,它在 EndlessAdapter.java 的第 29 行显示 NullPointerException,第 29 行是return itemList.size();getCount() 方法。

以下是错误日志:

02-05 14:22:37.734: E/AndroidRuntime(15402): FATAL EXCEPTION: main
02-05 14:22:37.734: E/AndroidRuntime(15402): java.lang.RuntimeException: Unable to resume activity {com.example.endlesslistdemo/com.example.endlesslistdemo.MainActivity}: java.lang.NullPointerException
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2602)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2630)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2116)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread.access$600(ActivityThread.java:134)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1251)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.os.Looper.loop(Looper.java:137)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread.main(ActivityThread.java:4666)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at java.lang.reflect.Method.invokeNative(Native Method)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at java.lang.reflect.Method.invoke(Method.java:511)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at dalvik.system.NativeStart.main(Native Method)
02-05 14:22:37.734: E/AndroidRuntime(15402): Caused by: java.lang.NullPointerException
02-05 14:22:37.734: E/AndroidRuntime(15402):    at com.example.endlesslistdemo.EndlessAdapter.getCount(EndlessAdapter.java:29)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.widget.ListView.setAdapter(ListView.java:464)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at com.example.endlesslistdemo.EndlessListView.setAdapter(EndlessListView.java:76)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at com.example.endlesslistdemo.MainActivity.onResume(MainActivity.java:51)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1159)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.Activity.performResume(Activity.java:4584)
02-05 14:22:37.734: E/AndroidRuntime(15402):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2588)
02-05 14:22:37.734: E/AndroidRuntime(15402):    ... 12 more

我已经在 AndroidManifest.xml 文件中授予了 INTERNET 权限。

编辑:

以下是我的 XMLParser 代码

public String getXMLFromUrl ( String url )
{
    String xml = "";

    try
    {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost ( url );
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        xml = EntityUtils.toString(entity);
    }
    catch ( Exception e )
    {
        e.printStackTrace();
    }

    return xml;
}

在这一行HttpPost httpPost = new HttpPost ( url );它给了我NPE。

4

3 回答 3

0

好的,我自己解决了问题,问题是由于NetworkOnMainThreadException. 我在 OnCreate() 方法中添加了以下代码,现在它工作正常。

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
于 2014-02-05T09:43:03.933 回答
0
private List<String> getXMLList()
{
    data = new ArrayList<String>();

    try
    {
        XMLParser parser = new XMLParser();
        String xml = parser.getXMLFromUrl( "http://www.vogella.com/article.rss" );
        Document doc = parser.getDomElement(xml);

        NodeList nl = doc.getElementsByTagName( KEY_ITEM );

        for ( int i = 0 ; i < nl.getLength() ; i++ )
        {
            Element el = (Element) nl.item( i );
            data.add( parser.getValue( el, KEY_LINK ) );
        }
    }
    catch ( Exception e ) { System.out.println ( "Error : " + e.toString() ); }

    return data;
}

如果您将gemXMLList方法修改为从不返回 null,您会修复 NPE,但用户不会看到错误。在这种情况下,您可以考虑添加功能以显示错误。

public String getXMLFromUrl(String url) {
    String xml = "";

    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        xml = EntityUtils.toString(entity);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return xml;
}

基于您的评论 url 在这里可能为空,因为它正在将 NPE 放入队列中HttpPost httpPost = new HttpPost(url);

于 2014-02-05T09:06:44.013 回答
-1

private List<String> getXMLList()如果方法失败,则该方法返回 null。将其更改为:

  private List<String> getXMLList()
  {
      data = new ArrayList<String>();

      try
      {
          XMLParser parser = new XMLParser();
          String xml = parser.getXMLFromUrl( "http://www.vogella.com/article.rss" );
          Document doc = parser.getDomElement(xml);

          NodeList nl = doc.getElementsByTagName( KEY_ITEM );

          for ( int i = 0 ; i < nl.getLength() ; i++ )
          {
              Element el = (Element) nl.item( i );
              data.add( parser.getValue( el, KEY_LINK ) );
          }
      }
      catch ( Exception e ) { System.out.println ( "Error : " + e.toString() ); }

      return data;
  }
于 2014-02-05T09:07:17.663 回答