我遇到了一个问题:我正在开发一个android应用程序,必须解析一些信息。我正在使用AsyncTask解析url中的信息,我已经成功地解析了一些信息,在方法onPostExecute()
中,我调用了一个方法,该方法在将显示在片段中的TextView中显示解析的信息。我的应用程序由Fragments分隔,但每次运行应用程序时,我在名为title的TextView中设置文本的行中都会出现NullPointerException
在onPostExecute
中,我调用方法displayText()
,在该方法中,我更新标题变量。以下是代码的一部分,因此您可以轻松理解:
这是片段
public class WeatherActivity extends Fragment{
TextView title;
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
super.onCreateView(inflater, container, savedInstanceState);
View view=inflater.inflate(R.layout.weather_activity, container,false);
title=(TextView)view.findViewById(R.id.weatherTitle);
return view;
}
public void displayWeather(Weather weather){
title.setText(weather.getTitle());//this is the line that gives me the NPE
}
}
这是使解析的类
public class WeatherManager extends AsyncTask<Void,Void,Void>{
public static final String WEATHER_URL="some url";
Weather weather;
WeatherActivity wa=new WeatherActivity();
@Override
protected Void doInBackground(Void... params) {
loadXML();//does the parsing
return null;
}
protected void onPostExecute(Void result) {
wa.displayWeather(weather);//calls to update fragment
}
public void loadXML(){
//does all the work and returns the info in an object weather
}
}
这是我的xml。目前,我只有一个TextView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/weatherTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="?android:attr/textAppearanceLarge" />
这是我的LogCat
E/AndroidRuntime(27441): FATAL EXCEPTION: main
E/AndroidRuntime(27441): Process: com.example.test23, PID: 27441
E/AndroidRuntime(27441): java.lang.NullPointerException
E/AndroidRuntime(27441): at com.example.test23.WeatherActivity.displayWeather(WeatherActivity.java:25)
E/AndroidRuntime(27441): at com.example.test23.WeatherManager.onPostExecute(WeatherManager.java:30)
E/AndroidRuntime(27441): at com.example.test23.WeatherManager.onPostExecute(WeatherManager.java:1)
编辑这是我创建选项卡/片段的主要活动
public class MainActivity extends FragmentActivity{
private String tabs[]={"Some String that will display the name of the tabs"};
ViewPager viewPager=null;
FragmentManager fragmentManager=getSupportFragmentManager();
AdapterView adapterView;
private Fragment fragment;
private Activity activity;
static List<Item> news=new ArrayList<Item>();
ArrayList<Item> sports=new ArrayList<Item>();
ArrayList<Item> articles=new ArrayList<Item>();
public static final int TIME_ENTRY_REQUEST_CODE=1;
static ParseManager parser=new ParseManager();
JSONManager jmanager=new JSONManager();
WeatherManager weather=new WeatherManager();
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager=(ViewPager)findViewById(R.id.pager);
viewPager.setAdapter(new AdapterView(fragmentManager));
viewPager.setOffscreenPageLimit(6);
adapterView=new AdapterView(getSupportFragmentManager());
final android.app.ActionBar actionbar=getActionBar();
ColorDrawable color=new ColorDrawable(Color.parseColor("#cd853f"));
actionbar.setBackgroundDrawable(color);
actionbar.setTitle("App title");
ActionBar.TabListener tabListener=new ActionBar.TabListener() {
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
};
/*Displaying Tabs for the app */
for(int i=0;i<tabs.length;i++) actionbar.addTab(actionbar.newTab().setText(tabs[i]).setTabListener(tabListener));
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionbar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
parser.execute();//Asynctask
jmanager.execute();
weather.execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onDestroy(){
super.onDestroy();
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.option1:
Intent intentContact=new Intent(this,SomeClass.class);
startActivityForResult(intentContact,TIME_ENTRY_REQUEST_CODE);
return true;
case R.id.option2:
Intent intentAbout=new Intent(this,SomeOtherClass.class);
startActivityForResult(intentAbout,TIME_ENTRY_REQUEST_CODE);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void onRefreshClicked(MenuItem refresh);
}
}
感谢您的帮助,如果您需要更多信息,请告诉我。提前谢谢。
我看到了几个问题:
1( 您不应该通过调用Fragment
的构造函数来实例化它。Android的工作是通过FragmentManager
类为您做到这一点。
2( 您正在尝试使用wa
Fragment
变量来调用它上的方法。虽然这在常规Java类中是有意义的。Fragments
有自己的生命周期。此生命周期的一部分是onCreateView()
状态。在onCreateView()
中,系统希望您放大要显示的布局。现在,您通过调用Fragment
的构造函数来创建它的实例,然后立即调用一个引用尚未膨胀的TextView
的方法;因此不存在CCD_ 13,所以它是CCD_。
正如@emmanuel所解释的,在您的片段附加到活动之前,不会调用片段内的onCreateView
。因此,textView未初始化并且为null。
在显示片段对象之前,不应该对其调用任何方法
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.your_placehodler, new YourFragment());
ft.commit();
在这一行之后,调用片段的onCreateView
,并在活动的R.id.your_placehodler
中显示由此返回的view
。
现在调用displayWeather
不会导致NLP。