简体   繁体   English

Android:访问内部AsyncTask类的变量,但在片段的onCreateView中将其获取为null

[英]Android: Accessing a variable of an inner AsyncTask class but getting it as null in onCreateView of a fragment

I have the following codes which get the value of LDR sensor from the cloud. 我有以下代码从云中获取LDR传感器的价值。 The variable which I am trying to access is ldrVal but when I am trying to access that value outside that inner class I am getting it as 0 when I am printing it in a Toast . 我尝试访问的变量是ldrVal但是当我尝试在该内部类之外访问该值时,在Toast打印该变量时,该变量的值为0。 However, when I printed it in a Runnable in the inner AsyncTask class, I got the correct non-zero ldr value. 但是,当我在内部AsyncTask类的Runnable中打印它时,我得到了正确的非零ldr值。

public class AutomatedControlsFragment extends Fragment {
        public int ldrVal=0;

    @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            new UbidotsConnection().execute();
        }

        public class UbidotsConnection extends AsyncTask{
            private final String API_KEY = "XXXXXXXXXXXXXXXXX";
            private final String UBIDOTS_ID_FOR_LIGHT1 = "XXXXXXXXXXXXX";
            Value[] ldrValues;

            @Override
            protected Object doInBackground(Object[] params){
                ApiClient apiClient = new ApiClient(API_KEY);
                light= apiClient.getVariable(UBIDOTS_ID_FOR_LIGHT1);
                ldrValues= light.getValues();

                ldrVal= (int) ldrValues[0].getValue();
                //Toast.makeText(getActivity().getApplicationContext(), "ldr value: "+ldrVal,Toast.LENGTH_LONG).show();

                //toast giving correct value
                getActivity().runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getActivity().getApplicationContext(), "ldr value: "+ldrVal, Toast.LENGTH_SHORT).show();
                    }
                });

                return null;
            }
    @Override
    protected void onPostExecute(Object o) {
        ldrVal= (int) ldrValues[0].getValue();
    }
        }

     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View view = inflater.inflate(R.layout.fragment_automated, container, false);

            //toast giving 0
            Toast.makeText(getActivity().getApplicationContext(), "ldr value: "+ldrVal,Toast.LENGTH_LONG).show();

      return view; 
    }
}

The Toast on the onCreateView shows ldr value: 0 while the Toast in the AsyncTask shows ldr value: 90 . onCreateView上的Toast显示ldr value: 0而AsyncTask中的Toast显示ldr value: 90 I need to access the variable ldrVal in onCreateView with its latest value. 我需要使用其最新值访问onCreateView的变量ldrVal

I think the value is showing correctly. 我认为该值显示正确。 I do not understand what do you want exactly. 我不明白你到底想要什么。 However, the values stored in lrdVal is fetched in the doInBackground method of your AsyncTask and then its initialized inside the AsyncTask . 但是,存储在lrdVal的值是在AsyncTaskdoInBackground方法中获取的,然后在AsyncTask对其进行了初始化。 So the Toast is showing the non-zero value while inside your onCreateView function you are not getting the value, as the value is not set yet. 因此,在onCreateView函数内部, Toast将显示非零值,但您尚未获得该值,因为尚未设置该值。

You need to check the Fragment lifecycle here, which clearly shows that the onCreateView is called before onActivityCreated . 您需要在此处检查Fragment生命周期 ,这清楚地表明onCreateViewonActivityCreated之前被调用。 You are calling the new UbidotsConnection().execute(); 您正在调用new UbidotsConnection().execute(); method inside onActivityCreated which is initializing the value based on the code segment you have shared. onActivityCreated内部的方法,该方法根据您共享的代码段初始化值。 So I think the behaviour is correct based on your implementation. 因此,根据您的实现,我认为该行为是正确的。

I'm not sure if either of them is possible though. 我不确定它们中的任何一个是否可能。 I have to access ldrVal in onCreateView in order to perform some operations on it based if it exceeds a certain value. 我必须在onCreateView中访问ldrVal ,以便在其超过某个值的基础上对其执行一些操作。

You cannot get the updated value of ldrVal inside your onCreateView . 您无法在onCreateView获取ldrVal的更新值。 Take the actions necessary inside your doInBackgroud method or inside the onPostExecute function of your AsyncTask where your updated value will be available for ldrVal . doInBackgroud方法内或AsyncTaskonPostExecute函数内执行必要的操作,其中更新后的值可用于ldrVal

I fetched ldrVal in onPostExecute but I still got it as 0 when I displayed variable in a Toast in onCreateView. 我在onPostExecute中获取了ldrVal,但是当在onCreateView中的Toast中显示变量时,我仍然将其设为0。 Here is what I did: @Override protected void onPostExecute(Object o) { ldrVal= (int) ldrValues[0].getValue(); 这是我所做的:@Override protected void onPostExecute(Object o){ldrVal =(int)ldrValues [0] .getValue(); } }

Instead of passing a generic Object o , you might consider passing the array instead, in your onPostExecute function. 您可以考虑在onPostExecute函数中传递数组,而不是传递通用Object o

public class UbidotsConnection extends AsyncTask<Void, Void, Value[]> {
    private final String API_KEY = "XXXXXXXXXXXXXXXXX";
    private final String UBIDOTS_ID_FOR_LIGHT1 = "XXXXXXXXXXXXX";

    @Override
    protected Value[] doInBackground(Void... params) {
        ApiClient apiClient = new ApiClient(API_KEY);
        light = apiClient.getVariable(UBIDOTS_ID_FOR_LIGHT1);
        Value[] ldrValues = light.getValues();

        ldrVal = (int) ldrValues[0].getValue();
        //Toast.makeText(getActivity().getApplicationContext(), "ldr value: "+ldrVal,Toast.LENGTH_LONG).show();

        //toast giving correct value
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getActivity().getApplicationContext(), "ldr value: " + ldrVal, Toast.LENGTH_SHORT).show();
            }
        });

        return ldrValues;
    }

    @Override
    protected void onPostExecute(Value[] values) {
        ldrVal = (int) values[0].getValue();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM