来自onPostExecute中AsyncTask的setText [英] setText from AsyncTask in onPostExecute

查看:61
本文介绍了来自onPostExecute中AsyncTask的setText的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下AsyncTask来从xml文件中获取一些数据:

I have the following AsyncTask to get some data from a xml file:

public class GetTripDetails extends AsyncTask<String, Integer, String[]> {

    private Context context;
    private String[] details = new String[4];

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    public GetTripDetails (Context parsedContext){
        context = parsedContext;
    }

    @Override
    protected String[] doInBackground(String... params) {
        SharedPreferences sharedpreferences;
        String activeTrip;

        try {
            sharedpreferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
            activeTrip = sharedpreferences.getString("activeTrip", null); //Liest den Namen des aktiven Trips

            File file = new File(Environment.getExternalStorageDirectory() + "/" + "android/data/com.travip/" + activeTrip + ".trp");
            FileInputStream fis = new FileInputStream(file);

            XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
            XmlPullParser myparser = xmlFactoryObject.newPullParser();
            myparser.setInput(fis, null);

            int event = myparser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT)  {
                String tag_name = myparser.getName();
                switch (event){
                    case XmlPullParser.START_TAG:
                        break;
                    case XmlPullParser.END_TAG:
                        if(tag_name.equals("trip")){
                            details[0] = myparser.getAttributeValue(null, "name");
                            details[1] = myparser.getAttributeValue(null, "startdate");
                            details[2] = myparser.getAttributeValue(null, "enddate");
                            details[3] = myparser.getAttributeValue(null, "description");
                        }
                        break;
                }
                event = myparser.next();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }

        return details;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(String[] result) {
        Toast.makeText(context, result[0], Toast.LENGTH_LONG).show();

        tv_title.setText(result[0]);
        tv_subtitle.setText(result[1] + " - " + result[2]);

        super.onPostExecute(result);
    }

}

尽管tv_title和tv_subtitle是公共的,并且AsyncTask在同一个类中,但它会产生一个空指针实例.我试图在onStart()中执行它(在TextViews应该已经初始化之后,->),但是它也不起作用. 感谢您的建议

It produces an null pointer exeption, although tv_title and tv_subtitle are public and the AsyncTask is in the same class. I tried to execute it in onStart() (-> after the TextViews should have been initialized), but it didn't work either. Thanks for your advice

Upadte:
logcat:

Upadte:
logcat:

08-08 12:09:01.446 22390-22390/com.travip E/AndroidRuntime: FATAL EXCEPTION: main
                                                        Process: com.travip, PID: 22390
                                                        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.travip/com.travip.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
                                                            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2440)
                                                            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500)
                                                            at android.app.ActivityThread.access$900(ActivityThread.java:163)
                                                            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362)
                                                            at android.os.Handler.dispatchMessage(Handler.java:102)
                                                            at android.os.Looper.loop(Looper.java:148)
                                                            at android.app.ActivityThread.main(ActivityThread.java:5585)
                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
                                                         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
                                                            at com.travip.MainActivity$GetTripDetails.onPreExecute(MainActivity.java:192)
                                                            at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:604)
                                                            at android.os.AsyncTask.execute(AsyncTask.java:551)
                                                            at com.travip.MainActivity.onCreate(MainActivity.java:88)
                                                            at android.app.Activity.performCreate(Activity.java:6279)
                                                            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
                                                            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393)
                                                            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500) 
                                                            at android.app.ActivityThread.access$900(ActivityThread.java:163) 
                                                            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362) 
                                                            at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                            at android.os.Looper.loop(Looper.java:148) 
                                                            at android.app.ActivityThread.main(ActivityThread.java:5585) 
                                                            at java.lang.reflect.Method.invoke(Native Method) 
                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 

完整代码:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, Overview.OnFragmentInteractionListener, Activities.OnFragmentInteractionListener, Marked.OnFragmentInteractionListener, Map.OnFragmentInteractionListener, Nearby.OnFragmentInteractionListener {
NavigationView navigationView;
String activeMenu;

public ImageView expand_collapse;
public TextView tv_title;
public TextView tv_subtitle;
public View headerLayout;

DrawerLayout drawer;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    Mapbox.getInstance(getApplicationContext(), getString(R.string.access_token));

    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setCheckedItem(R.id.nav_overview); //Setzt den aktiven Menüeintrag
    activeMenu = "main";

    headerLayout = navigationView.getHeaderView(0);
    headerLayout.setOnClickListener(new View.OnClickListener() { //Ändert das Menü, wenn auf den Header gecklickt wird
        @Override
        public void onClick(View v) {
            toggleMenu();
        }
    });

    expand_collapse = (ImageView) headerLayout.findViewById(R.id.expand_collapse);
    tv_title = (TextView) headerLayout.findViewById(R.id.tv_name);
    tv_subtitle = (TextView) headerLayout.findViewById(R.id.subtitle);

    new GetTripDetails(getApplicationContext()).execute();
}
//Here is the asynctask (see above)

}

更新2:
logcat(初始化TextViews后):

Update 2:
logcat (after initializing TextViews):

08-08 12:20:59.008 934-934/com.travip E/AndroidRuntime: FATAL EXCEPTION: main
                                                    Process: com.travip, PID: 934
                                                    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
                                                        at com.travip.MainActivity$GetTripDetails.onPostExecute(MainActivity.java:255)
                                                        at com.travip.MainActivity$GetTripDetails.onPostExecute(MainActivity.java:183)
                                                        at android.os.AsyncTask.finish(AsyncTask.java:651)
                                                        at android.os.AsyncTask.access$500(AsyncTask.java:180)
                                                        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
                                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                                        at android.os.Looper.loop(Looper.java:148)
                                                        at android.app.ActivityThread.main(ActivityThread.java:5585)
                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

更新3:
nav_header_main.xml(导航抽屉的headerLayout(位于TextView所在的位置)):

Update 3:
nav_header_main.xml (headerLayout of the navigation drawer (Where the TextViews are located)):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:id="@+id/nav_header_main" >

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/nav_header_top"
    android:background="?attr/selectableItemBackground">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/nav_header_vertical_spacing"
        android:id="@+id/title"
        android:text="Spanien"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"
        android:id="@+id/subtitle"
        android:text="21.3.17 - 1.4.17"
        android:textAppearance="@style/TextAppearance.AppCompat.Small" />

    <ImageView
        android:id="@+id/expand_collapse"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:src="@drawable/ic_expand"
        android:background="?attr/actionBarItemBackground"/>

</RelativeLayout>

activity_main.xml:

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

<include
    layout="@layout/fragment_overview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment_container"/>

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

 </android.support.v4.widget.DrawerLayout>

推荐答案

为避免在上下文中发生内存泄漏,建议您将GetTripDetails类设置为静态,并用适当的回调接口替换构造函数中的上下文参数,以返回您的任务活动的结果.当然,它也可以解决您的问题,因为在您的情况下,不会设置任务的引用.

To avoid memory leak on your context, I recommend you to make your GetTripDetails class static, and replace context param in constructor with an appropriate callback interface who returns your task results to your activity. It'll also certainly resolve your problem, because in your case, no reference of your task is set.

static class GetTripDetails extends AsyncTask<String, Void, String[]> {

    private WeakReference<Callback> callbackRef;

    public GetTripDetails(final Callback callback){
        callbackRef = new WeakReference<>(callback);
    }

    @Override
    protected String[] doInBackground(String... params) {
        // Do your stuff
        return details;
    }

    @Override
    protected void onPostExecute(String[] result) {
        final Callback callback = callbackRef.get();
        if (callback == null) {
            return;
        }
        callback.onResult(result);
    }

    interface Callback {
        void onResult(String[] result);
    }

}

您的活动中:

private final Callback callback = new Callback() {
    void onResult(String[] result) {
        // set values in your textview..
    } 
}

private GetTripDetails task;

@Override 
protected void onCreate(Bundle savedInstanceState) {
    //...
    task = new GetTripDetails(callback);
    task.execute(); 
}

这篇关于来自onPostExecute中AsyncTask的setText的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆