【问题标题】:How to update UI from separate AsynkTask class如何从单独的 AsyncTask 类更新 UI
【发布时间】:2016-07-04 17:01:16
【问题描述】:

我有一个 CDealListing 类,我从那里执行 AsynkTask 类,它是一个单独的类,我想要更新 AsynkTask 类 onPost 方法上的 CDealListing 类的 UI。请帮助我.....

这是我的课程 CDealListing 的代码

public class CDealAppListing extends Fragment {
public static String m_DealListingURL = "http://192.166.0.110:8080/ireward/rest/json/metallica/getDealListInJSON";
public static String s_szresult = " ";
public static RecyclerView m_RecyclerView;
public static CDealAppListingAdapter m_oAdapter;
public static CDealAppDatastorage item;
public ArrayList<CDealAppDatastorage> s_oDataset;
public int[] m_n_FormImage;
public View m_Main;
public CRegistrationSessionManagement m_oSessionManagement;
public String m_szMobileNumber, m_szEncryptedPassword;
public LinearLayoutManager mLayoutManager;
public AppCompatButton m_showMore;
public ProgressBar mProgressBar;
public int m_n_DefaultRecordCount = 5;// intiallly record count is 5.
public int m_n_DeafalutLastCount = 0;//initally lastcount is 0.

public String sz_RecordCount, sz_LastCount;
//declare boolean
private CJsonsResponse m_oJsonsResponse;


@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    m_Main = inflater.inflate(R.layout.deal_app_listing, container, false);//intialize mainLayout
    new CDealDataSent().execute(m_DealListingURL);
    init();//initialize method
    implementScroll();
    return m_Main;
}

public void init() {
    mProgressBar = (ProgressBar) m_Main.findViewById(R.id.progressBar1);
    mProgressBar.setVisibility(View.GONE);

    m_showMore = (AppCompatButton) m_Main.findViewById(R.id.show_more);
    m_showMore.setBackgroundColor(Color.TRANSPARENT);
    m_showMore.setVisibility(View.GONE);
    // Getting the string array from strings.xml
    m_n_FormImage = new int[]{
            R.drawable.amazon,
            R.drawable.whatsapp,
            R.drawable.zorpia,
            R.drawable.path,
            R.drawable.app_me,
            R.drawable.evernote,
            R.drawable.app_me};

    m_RecyclerView = (RecyclerView) m_Main.findViewById(R.id.my_recycler_view);//finding id of recyclerview
    m_RecyclerView.setItemAnimator(new DefaultItemAnimator());//setting default animation to recyclerview
    m_RecyclerView.setHasFixedSize(true);//fixing size of recyclerview
    mLayoutManager = new LinearLayoutManager(getActivity());
    m_RecyclerView.setLayoutManager(mLayoutManager);//showing odata vertically to user.
    m_oSessionManagement = new CRegistrationSessionManagement(getActivity());
    HashMap<String, String> user = m_oSessionManagement.getRegistrationDetails();
    m_szEncryptedPassword = user.get(m_oSessionManagement.s_szKEY_PASSWORD);
    m_szMobileNumber = user.get(m_oSessionManagement.s_szKEY_MOBILENUMBER);

    sz_RecordCount = String.valueOf(m_n_DefaultRecordCount);// increment of record count
    sz_LastCount = String.valueOf(m_n_DeafalutLastCount);
}

public void implementScroll() {
    m_RecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState ==  RecyclerView.SCROLL_STATE_IDLE){

            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (dy > 0) {

                m_showMore.setVisibility(View.VISIBLE);
                m_showMore.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //change boolean value
                        m_showMore.setVisibility(View.GONE);
                        m_n_DefaultRecordCount = m_n_DefaultRecordCount + 5;
                        m_n_DeafalutLastCount = m_n_DeafalutLastCount + 5;

                        sz_RecordCount = String.valueOf(m_n_DefaultRecordCount);
                        sz_LastCount = String.valueOf(m_n_DeafalutLastCount);
                        new DealNext().execute(m_DealListingURL);
                    }
                });
            } else {
                m_showMore.setVisibility(View.GONE);
            }
        }
    });
}
//sending deal data to retreive response from server
public String DealListing(String url, CRegistrationDataStorage login) {
    InputStream inputStream = null;
    m_oJsonsResponse = new CJsonsResponse();
    try {
        // 1. create HttpClient
        HttpClient httpclient = new DefaultHttpClient();
        // 2. make POST request to the given URL
        HttpPost httpPost = new HttpPost(url);
        String json = "";
        // 3. build jsonObject
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("agentCode", m_szMobileNumber);
        jsonObject.put("pin", m_szEncryptedPassword);
        jsonObject.put("recordcount", sz_RecordCount);
        jsonObject.put("lastcountvalue", sz_LastCount);
        //jsonObject.put("emailId", "nirajk1190@gmail.com");
        // 4. convert JSONObject to JSON to String
        json = jsonObject.toString();
        // 5. set json to StringEntity
        StringEntity se = new StringEntity(json);
        // 6. set httpPost Entity
        httpPost.setEntity(se);
        // 7. Set some headers to inform server about the type of the content
        httpPost.setHeader("Content-type", "application/json");
        // 8. Execute POST request to the given URL
        HttpResponse httpResponse = httpclient.execute(httpPost);
        HttpEntity entity = httpResponse.getEntity();
        // 9. receive response as inputStream
        inputStream = entity.getContent();
        System.out.println("InputStream....:" + inputStream.toString());
        System.out.println("Response....:" + httpResponse.toString());

        StatusLine statusLine = httpResponse.getStatusLine();
        System.out.println("statusLine......:" + statusLine.toString());
        ////Log.d("resp_body", resp_body.toString());
        int statusCode = statusLine.getStatusCode();
        // 10. convert inputstream to string
        if (statusCode == 200) {
            // 10. convert inputstream to string
            if (inputStream != null)
                s_szresult = m_oJsonsResponse.convertInputStreamToString(inputStream);
            //String resp_body =
            EntityUtils.toString(httpResponse.getEntity());
        } else
            s_szresult = "Did not work!";
    } catch (Exception e) {
        Log.d("InputStream", e.getLocalizedMessage());
    }
    System.out.println("resul.....:" + s_szresult);
    // 11. return s_szResult
    return s_szresult;
}

这是我的 AsynkTask 类

/   sending deal data to server and retreive response......
class CDealDataSent extends AsyncTask<String, Void, String> {
    public JSONObject m_oResponseobject;
    public ProgressDialog m_PDialog;
    public CRegistrationDataStorage oRegisterStorage;
    public CDealAppDatastorage item;

    //      @Override
    protected void onPreExecute() {
        super.onPreExecute();
        m_PDialog = new ProgressDialog(getActivity());
        m_PDialog.setMessage("Please wait while Loading Deals...");
        m_PDialog.setCancelable(false);
        m_PDialog.show();
    }
    @Override
    protected String doInBackground(String... urls) {
        return DealListing(urls[0], oRegisterStorage);// sending data to server...

    }
    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {

        m_PDialog.dismiss();
        try {
            m_oResponseobject = new JSONObject(result);// getting response from server
            final JSONArray posts = m_oResponseobject.optJSONArray("dealList");

            s_oDataset = new ArrayList<CDealAppDatastorage>();
            for (int i = 0; i < posts.length(); i++) {
                JSONObject post = posts.getJSONObject(i);
                item = new CDealAppDatastorage();
                item.setM_szHeaderText(post.getString("dealname"));
                item.setM_szsubHeaderText(post.getString("dealcode"));
                item.setM_n_Image(m_n_FormImage[i]);
                s_oDataset.add(item);

            }
            getResponse();

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void getResponse() throws JSONException {
        if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Transaction Successful")) {

            m_oAdapter = new CDealAppListingAdapter(s_oDataset);//creating object of adapter and addd setting odata to adapter for use.
            m_RecyclerView.setAdapter(m_oAdapter);//adding adapter to recyclerview
        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Connection Not Available")) {
            Toast.makeText(getActivity(), "Connection not avaliable", Toast.LENGTH_SHORT).show();
        }else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Deal List Not Found")){
            Toast.makeText(getActivity(),"No More Deals",Toast.LENGTH_SHORT).show();
        }
        System.out.println("agentCode...." + m_szMobileNumber);
        System.out.println("password...." + m_szEncryptedPassword);
        System.out.println("record////" + sz_RecordCount);
        System.out.println("last:........" + sz_LastCount);
    }

}

在asynkTask类中获取CDealListing类的Response方法更新UI

【问题讨论】:

    标签: android


    【解决方案1】:

    一种方法是声明一个侦听器接口并将该接口的一个实例(或者可能是一个 Runnable)传递给 AsyncTask 的构造函数。

    在您的片段代码中:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ...        
        new CDealDataSent(new Runnable() {
            @Override
            public void run() {
                // perform update UI code here
            }
        }).execute(m_DealListingURL);
        ...
    }
    

    在您的 AsyncTask 代码中:

    class CDealDataSent extends AsyncTask<String, Void, String> {
        private final Runnable mOnPostExecuteRunnable;
        CDealDataSent(Runnable onPostExecuteRunnable) {
            mOnPostExecuteRunnable = onPostExecuteRunnable;
        }
    
        ...
    
        @Override
        protected void onPostExecute(String result) {
            ...
            if (mPostExecuteRunnable != null) {
                mPostExecuteRunnable.run();
            }
            ...
        }
    }
    

    您还可以从片段中使用 AsyncTask 的匿名子类并覆盖 onPostExecute():

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ...        
        new CDealDataSent() {
            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result); // be sure to call super first to do normal processing
                ... // update your UI here
            }
        }.execute(m_DealListingURL);
        ...
    }
    

    请注意,如果您不小心,这两种解决方案都容易出现 Activity/Fragment 泄漏,因为 Runnable/匿名子类的父类被保留为隐式引用。如果用户在 onDestroy() 中退出您的活动,请务必取消任何未完成的 AsyncTask。

    您可以通过静态嵌套类缓解任何潜在的泄漏问题,或者可以将 Handler 实例传递给 AsyncTask,以便它在 onPostExecute() 完成其工作时发送消息。有关此问题的讨论,请参阅 What's the correct way to implement AsyncTask? static or non static nested class?

    【讨论】:

    • 但是我怎样才能让progressdialog可见
    【解决方案2】:

    有3种方式

    1. onPostExecute() 中调用Fragment 的某些方法
    2. onPostExecute() 中使用BroadcastReceiver
    3. 使用EventBus 库将事件传递给您的Fragment

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-04
      • 2017-08-02
      • 2017-06-23
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多