片段内部onPostExecute中的带有AsyncTask的TextView的setText中的NPE



我遇到了一个问题:我正在开发一个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。

相关内容

最新更新