簡體   English   中英

如何在Android中處理后按按鈕而又不會再次觸及網絡

[英]How to handle the back press button in Android without hitting the network again

我的應用程序中包含兩個屏幕。 解析xml並進行api調用后,我返回了廣告列表。 然后,每當我單擊recyclerView項時,都會顯示另一個活動,顯示有關該被單擊項的更多數據。 每當我按下“后退”按鈕時,都會發出新的api調用。 那么如何預防呢?

有什么建議嗎?

這是我的主要活動:

     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         // Setting the adapter and the recycler view

        loadPage();



    }
    public void loadPage() {
        new DownloadXmlTask().execute(URL);
    }

    private class DownloadXmlTask extends AsyncTask<String, Void, List<AdEntry>> {
        @Override
        protected List<AdEntry> doInBackground(String... urls) {
            try {
                return loadXmlFromNetwork(urls[0]);
            } catch (IOException e) {
                return null;
            } catch (XmlPullParserException e) {
                return null;
            }
        }
        @Override
        protected void onPostExecute(List<AdEntry> adEntries) {
            Toast.makeText(MainActivity.this, "Successfully Processed", Toast.LENGTH_SHORT).show();
            mAdsAdapter.setAdData(adEntries);
            entryList = adEntries;
            super.onPostExecute(adEntries);
        }
    }


    public List<AdEntry> loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
        InputStream stream = null;
        try {
            stream = downloadUrl(urlString);
            entryList = parse(stream);
        } finally {
            if (stream != null)
                stream.close();
        }
        return entryList;
    }

    public InputStream downloadUrl(String urlString) throws IOException {
         // Open HttpURLConnection
        }


    @Override
    public void onClick(View view, int position) {
      //Some code
    }

您使用哪種生命周期方法進行api調用? 例如, onCreate將是您可以進行api調用的方法,該方法在活動的生命周期中(即創建或重新創建您的活動時)僅被調用一次。onStartonResume將在您的活動再次變得可見時被調用,我猜猜這就是您的情況。

可以通過重寫onBackPressed來處理后按,但是如果不編寫很多不必要的代碼,那么對您的問題將無濟於事。

因此,嘗試在onCreate中進行api調用。

您在正確的位置調用了api。 我想問題是完成了mainActivity,然后轉到第二個活動。 因此,如果您需要使用后退按鈕並返回到mainActivity,則不必完成mainActivity,通過這種方法,onCreate不會再次觸發。 並在此處檢查活動生命周期

確保首先檢查Android生命周期的工作方式( https://developer.android.com/guide/components/activities/activity-lifecycle )。 它將幫助您決定首先在哪里調用API( onCreate可能是這樣做的地方)

當您返回上一個活動時,它通常會調用onResume方法。

您可能還需要考慮保存活動狀態,消除再次調用該API的必要性,或者考慮使用一種緩存以避免多次調用該API。

==更新==

A.將您的應用程序的啟動模式更改為單實例

    <activity android:name=".MainActivity"
        android:launchMode="singleInstance">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

    <activity
            android:name=".DetailActivity"
            android:label="@string/title_activity_detail"
            android:parentActivityName=".MainActivity">
        <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity"/>
    </activity>

B.配置您的適配器並在onCreate中查看。 啟動任務等

package com.example.mylist

import // ... all your imports

class MainActivity : AppCompatActivity(), BookLoadingTaskDelegate {
    private var listView: ListView? = null
    private var data: MutableList<Book> = mutableListOf()
    private lateinit var adapter: BooksAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        this.listView = findViewById(R.id.listView)
        this.adapter = BooksAdapter(this, data)

        loadNetworkIntensiveData()
    }

    override fun onResume() {
        super.onResume()

        this.listView!!.adapter = this.adapter
    }

    private fun loadNetworkIntensiveData() {
        LoadingTask(this).execute()
    }

    override fun processResult(result: List<Book>?) {
        Log.d("ProcessResult", "Found ${result?.size}")

        this.listView!!.post {
            data.addAll(result!!)
            Log.d("ProcessResult", "Found data elements: *${data.size}")
            adapter.notifyDataSetChanged()
        }

        this.listView!!.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
            val intent = Intent(this, DetailActivity::class.java)
            startActivity(intent)
        }
    }


    class LoadingTask(private val delegate: BookLoadingTaskDelegate) : AsyncTask<Void, Void, List<Book>>() {
        override fun doInBackground(vararg params: Void?): List<Book> {
            Log.w("Background task", "Loading heavy stuff in the background")

            val tempList: MutableList<Book> = mutableListOf()

            // ... Load data into the list

            return tempList
        }

        override fun onPostExecute(result: List<Book>?) {
            delegate.processResult(result)
        }
    }

    data class Book(
        val title: String,
        val summary: String
    )

    class BooksAdapter(private val context: Context, private val data: List<Book>) : BaseAdapter() {
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            Log.d("GetView", "Retrieving element at position $position")

            val book = getItem(position) as Book

            var v = //... do what you need to do to populate the view

            return v
        }

        override fun getCount(): Int {
            Log.d("Adapter - Get Count", "Size: ${data.size}")
            return data.size
        }

        override fun getItem(position: Int): Any? {
            return if (position > data.size) null else data[position]
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }
    }

}

interface BookLoadingTaskDelegate {
    fun processResult(result: List<MainActivity.Book>?)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM