問題と言うのは[基礎からのAndroidプログラミング]にてリストビューのカスタマイズを絡めたTwitterのアプリケーション(ただしパブリックタイムラインが廃止されたので擬似ですが)
を作成、実行後にメインアクティビティのonCreateすら通らずに、ActivityThread.javaの2195行目で例外処理が発生して強制終了してしまう問題です。
ActivityThreadは非常に大きいプログラムのようなのでそれ以外のソースを提示します。
TwitterActivity.java
package jp.denpa.twitterdammy;
import android.os.Bundle;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;
import android.widget.ListView;
import android.view.View;
import android.widget.AdapterView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ListActivity;
public class TwitterActivity extends ListActivity implements AdapterView.OnItemLongClickListener{
private static final String PROFILE_IMAGE_URL = "profile_image_url";
private static final String SCREEN_NAME = "screen_name";
private static final String TEXT = "text";
private static final String STATUS = "status";
private static final String TIMELINE = "http://www.geocities.jp/chopper1250/public_timeline.xml";
private TweetAdapter mAdapter;
ArrayList<Status> mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mList = parseTimeline();
if(mList != null){
mAdapter = new TweetAdapter(this, mList);
setListAdapter(mAdapter);
getListView().setOnItemLongClickListener(this);
}else{
Log.e("TwetterActivity", "タイムライン取得エラー");
}
}
//パブリックタイムラインを表示する
private ArrayList<Status> parseTimeline(){
ArrayList<Status> list = null;
try{
XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
URL url = new URL(TIMELINE);
URLConnection connection = url.openConnection();
xmlPullParser.setInput(connection.getInputStream(), "UTF-8");
String name;
Status status = null;
int eventType = xmlPullParser.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT){
switch(eventType){
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<Status>();
break;
case XmlPullParser.START_TAG:
name = xmlPullParser.getName();
if(status.equals(name)){
status = new Status();
}else if(status != null){
if(TEXT.equalsIgnoreCase(name)){
status.setText(xmlPullParser.nextText());
}else if(SCREEN_NAME.equalsIgnoreCase(name)){
status.setScreenName(xmlPullParser.nextText());
}else if(PROFILE_IMAGE_URL.equalsIgnoreCase(name)){
status.setProfileImageUrl(xmlPullParser.nextText());
}
}
break;
case XmlPullParser.END_TAG:
name = xmlPullParser.getName();
if(STATUS.equalsIgnoreCase(name)){
if(list != null && status != null){
list.add(status);
status = null;
}
}
break;
}
eventType = xmlPullParser.next();
}
}catch(MalformedURLException e){
Log.e("XmlPullParserSampleUrl",e.toString());
}catch(XmlPullParserException e){
Log.e("XmlPullParserSampleUrl",toString());
}catch(IOException e){
Log.e("XmlPullParserSampleUrl",e.toString());
}
return list;
}
//項目をタップしたときの処理
@Override
public void onListItemClick(ListView l, View v, int position, long id){
Status status = new Status();
status.setText("new data");
status.setScreenName("new name");
mAdapter.add(status);
}
//項目を長押しした時の処理
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id){
Status status = mAdapter.getItem(position);
mAdapter.remove(status);
return true;
}
}
package jp.denpa.twitterdammy;
public class Status {
private String text;
private String screenName;
private String profileImageUrl;
public String getText(){
return text;
}
public void setText(String text){
this.text=text;
}
public String getScreenName(){
return screenName;
}
public void setScreenName(String screenName){
this.screenName = screenName;
}
public String getProfileImageUrl(){
return profileImageUrl;
}
public void setProfileImageUrl(String profileImageUrl){
this.profileImageUrl = profileImageUrl;
}
@Override
public String toString(){
return screenName;
}
}
package jp.denpa.twitterdammy;
import java.util.List;
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 android.widget.TextView;
//リスト項目内のビューを保持するためのクラス
class ViewHolder{
ImageView image;
TextView screenName;
TextView text;
}
public class TweetAdapter extends ArrayAdapter<Status> {
private LayoutInflater mInflater;
//コンストラクタ
public TweetAdapter(Context context, List<Status> objects){
super(context, 0, objects);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
//リストの項目(1行)を作成する処理
@Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder;
if(convertView == null){
//ビューが無ければ作成
convertView = mInflater.inflate(R.layout.costom_list_cell, parent, false);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.image);
holder.screenName = (TextView) convertView.findViewById(R.id.screen_name);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
}else{
//ビューがあれば再利用
holder = (ViewHolder) convertView.getTag();
}
//項目内の各ビューに値をセットする
Status status = getItem(position);
holder.screenName.setText(status.getScreenName());
holder.text.setText(status.getText());
return convertView;
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
mInstrumentation.callActivityOnCreate(activity, r.state);
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) { //------------------------------------------------------ここで例外発生
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
java.lang.RuntimeException: Unable to start activity ComponentInfo{jp.denpa.twitterdammy/jp.denpa.twitterdammy.TwitterActivity}: java.lang.NullPointerException
NullPointerって言っているのはわかるんですがね・・・