我已成功为此tutorial创建了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行是getCount()方法的return itemList.size();
。
以下是错误日志:
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。
答案 0 :(得分: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;
}
基于您的评论网址可能在此处为空,因为它正在将NPE排成行HttpPost httpPost = new HttpPost(url);
答案 1 :(得分:0)
好的,我解决了自己的问题,问题归因于NetworkOnMainThreadException
。我在OnCreate()方法中添加了以下代码,现在工作正常。
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
答案 2 :(得分:-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;
}