我遇到了问题:我正在开发一个Android应用程序,我必须解析一些信息。我正在使用AsyncTask从URL解析信息,我已成功解析了一些信息并在方法onPostExecute()
中我调用一个方法,在TextView中显示解析的信息,该信息将显示在片段中。我的应用程序由Fragments分隔,但每次运行我的应用程序时,我都会在我在TextView中设置名为title的文本行中获得NullPointerException。
在onPostExecute
中,我调用方法displayText()
,在此方法中,我更新了title变量。这是代码的一部分,因此您可以轻松理解:
这是片段
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)
修改 这是我的MainActivity,用于创建标签/片段
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);
}
}
如有任何帮助,请联系我们。提前谢谢。
答案 0 :(得分:3)
我看到了几个问题:
1)你不应该通过调用它的构造函数来实例化Fragment
。 Android的工作是通过FragmentManager
类为您完成。
2)您正在尝试使用wa
Fragment
变量来调用方法。虽然这在常规Java类中是有意义的。 Fragments
有自己的生命周期。此生命周期的一部分是onCreateView()
状态。在onCreateView()
中,系统希望您扩展要显示的布局。现在,您正在通过调用其构造函数来创建Fragment
的实例,之后,您正在调用一个引用尚未膨胀的TextView
的方法;因此没有TextView
所以它是null
。
答案 1 :(得分:0)
正如@emmanuel解释的那样,片段内的onCreateView
在你的片段被附加到一个活动之前没有被调用。因此,textView未初始化且为null。
在显示片段对象之前,不应该调用任何方法。
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.your_placehodler, new YourFragment());
ft.commit();
调用此行onCreateView
后,{}返回的view
将显示在您的活动R.id.your_placehodler
内。
现在调用displayWeather
不会导致NLP。