編輯:關於android開發
2、如果有個100M大的文件,需要上傳至服務器中,而服務器form表單最大只能上傳2M,可以用什麼方法。
個人理解:所謂表單最大只能上傳2M,是不是指一個表單中附件只能上傳最大2M,如果是的話,現在要求上傳100M,為什麼不直接
把附件上傳大小設置為100M就可以了,除此菜鳥的我,並想不出這個題目究竟要考核面試者的什麼知識點。
標准答案:這個問題不是很明確我覺得,首先來說使用http協議上傳數據,特別在android下,跟form沒什麼關系。傳統的在web中,在form中寫文件上傳,其實浏覽器所做的就是將我們的數據進行解析組拼成字符串,以流的方式發送到服務器,且上傳文件用的都是POST方式,POST方式對大小沒什麼限制。回到題目,可以說假設每次真的只能上傳2M,那麼可能我們只能把文件截斷,然後分別上傳了。
二次理解:因為android程序中頁面都是活動和碎片,跟form沒有什麼關系,只有一個類似form的布局tablelayout,但跟form字面上都不是一回事,所以android並不存在form表單說法,應該是指html中form表單,那麼表單附件上傳中,首先把數據解析字符串,文件以IO流的方式上傳到服務器,而且並沒有上傳限制,如果有話,應該是什麼原因,防止長時間占用服務器,降低效率,那麼把文件截斷上傳還有意義嘛,這個問題不具備普遍性,所以不進行深究。
3、內存溢出和內存洩漏有什麼區別?何時會產生內存洩漏?內存優化有哪些方法?
個人理解:不知道他們的區別,以為是同一件事情,比如內存中創建的對象過多時,導致內容空間不夠,會產生該現象;及時關閉不必要的
資源,如數據庫連接、IO流等,另外可以通過代碼重構,盡可能減少對象的創建數量。
標准答案:
內存溢出通俗理解就是軟件(應用)運行需要的內存,超出了它可用的最大內存。
內存洩漏就是我們對某一內存空間的使用,使用完成後沒有釋放。
內存優化:Android中容易內存溢出的部分,就是圖片的加載,我們可以使用圖片的壓縮加上使用LruCache緩存的目的來控制圖片所能夠使用的內存。還有對於比較耗資源的對象及時的關閉,例如Database Conn , 各種傳感器, Service等等。
二次理解:內存溢出指內存超出它可用的最大內容,而內存洩露則特指使用的資源沒有釋放,而內容中容易內存溢出的就是存儲加載,使用壓縮和緩存的方式,而內存洩露則需要及時關閉資源,比如數據連接、服務等。概念話的內容,並沒有實際的參照價值,因為暫時沒有學習圖片加載的使用
4、AsyncTask使用在哪些場景?它的缺陷是什麼?如何解決?
個人理解:AsyncTask也是一種多線程的通信機制,但是AsyncTask並不需要去創建新的線程,把需要的操作直接定義在該對象的方法中就可以了,具體什麼方法忘記,在第一行代碼因為學習的Handler機制所以並沒有加深對AsyncTask的理解,至於它的缺陷和解決方式更是不清楚了。
標准答案:
AsyncTask 運用的場景就是我們需要進行一些耗時的操作,耗時操作完成後更新主線程,或者在操作過程中對主線程的UI進行更新。
缺陷:AsyncTask中維護著一個長度為128的線程池,同時可以執行5個工作線程,還有一個緩沖隊列,當線程池中已有128個線程,緩沖隊列已滿時,如果此時向線程提交任務,將會拋出RejectedExecutionException。
解決:由一個控制線程來處理AsyncTask的調用判斷線程池是否滿了,如果滿了則線程睡眠否則請求AsyncTask繼續處理。
二次理解:
AsyncTask與Handler機制類似,即異步消息處理機制,所謂異步,即是並行執行的意思,而多線程就是相互獨立"同時"在運行,而AsyncTask相對與Handler機制的不同,他對Handler進行了封裝,在使用時不需要走Handler的流程,直接在doInBackground()中定義相關方法,系統自動創建新子線程去執行。AsyncTask與Handler機制是功能是相似的,可以用來在子線程中更新UI,或者下載耗時比較久的操作,比如下載文件因為主線程頁面響應,即一個操作點擊後,頁面針對該操作做出反應的時間過長,那麼Android系統會認為是不友好的行為,該程序會直接崩潰。關於標准答案中AsyncTask可以維護一個長度為128的線程池,究竟是什麼概念,我可以理解為可以容納128線程嘛?但是我能想象到的就是手機App目前都是客戶端本地的模式,即C/S模式,基本不存在一個用戶在一個應用下打開128個下載內容,但不排除這個情況,然後執行5個工作線程的又是什麼意思,與128是否沖突,還是概念上有什麼差別(解答:所謂可以執行5個工作線程,長度為128的線程池,好比迅雷下載,你可以開啟128個下載任務,但是它只支持5個任務正在下載,超出的任務將進入緩沖區域,只有當前5個任務完結時,才會從緩沖區域獲取並執行新的任務,而超出128個任務時,則提示拒絕執行異常)。關於標准答案開辟一個子線程去監控線程緩沖區是否已滿,如果滿了,則讓請求的線程的睡眠,但是睡眠的時間怎麼設定?怎麼實現線程緩沖區空閒時,睡眠停止的工作。暫時還沒有找到更加詳細資料。
使用介紹:由於本人對AsyncTask的使用沒有更多的了解,所以這裡會講AsyncTask的簡單介紹和使用辦法。
特點1:AsyncTask,是一個抽象類,所以要使用必須要創建一個子類就繼承它。
特點2:AsyncTask,必須指定三個泛型參數,所謂類的泛型參數,可以認為是java的一種指定類中所關聯對象的具體類型做法,這種做法的意義就是可以限制或者是明確了對象類型的范圍,可以讓編譯器根據定義的泛型更加明確判定到內部代碼的正確性,這是解決程序執行時多態轉型異常的一種手段。參數列表為
最簡單的形式:class DownloadTask extendsAsyncTask
特點3:AsyncTask方法介紹:
代碼示例1:
UIActivity.xml
package com.noodles.uipractice; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; public class UIActivity extends AppCompatActivity { private TextView tv; private Button btn; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ui); tv = (TextView) findViewById(R.id.tv); progressBar = (ProgressBar) findViewById(R.id.progress_bar); btn = (Button) findViewById(R.id.send_text); /** * 4、給Button定義個點擊事件,就是啟動AsyncTask * 其中execute的參數Params內容會自動傳遞給doInBackground的字符串數組類型的參數 */ btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new MyAsyncTask().execute("http://www.baidu.com"); } }); } /** * 1、在主活動中中定義一個內部類MyAsyncTask繼承AsyncTask * 當然也可以不以內部類的形式,比如單獨定義一個類或者用匿名內部類 * 不覺哪種定義方式更具有優勢,因為單獨定義分離後而代碼結構更加清晰。 * 而匿名內部類和內部類更加貼近業務一體性。 */ class MyAsyncTask extends AsyncTask{ /** * 2、復寫doInBackground方法,該方法會開辟一個子線程去執行其中的代碼 * 一般都是進行一些耗時的操作,這裡可以去獲取百度首頁的內容 * * String... params形式的參數列表,可以看做String[] params */ @Override protected String doInBackground(String... params) { BufferedReader br = null; try { //首先把百度的首頁地址www.baidu.com,封裝成URL,就比如在浏覽器中用鍵盤輸入www.baidu.com URL url = new URL(params[0]); //調用URL的openConnnection方法,就好比在浏覽器的點擊了回車 URLConnection connection = url.openConnection(); //如果沒有下面這行話,則默認是調用GZIP的壓縮技術,getContentLength()返回的就是-1 connection.setRequestProperty("Accept-Encoding", "identity"); //connection.connect(); long Total = connection.getContentLength(); /* 建立連接以後,形成了socket通道,以IO流的方式形成數據的流轉,所謂IO流可以看作是計算機 * 所有媒介進行數據流轉的一種固定形式,只是剛好起了一個名字叫IO流。而我們建立連接後 * 默認是以get的方式想百度服務器請求數據,可以請求返回一個字節輸入流,即InputStream,而我們知道,返回 * 的內容都是字符串,所有可以通過InputStreamReader,把字節流轉換成字符流,因為java為字符流提供的方式 * 更加易用,同時java提供一個緩存區的BufferReader,本質就是數組,可以把單獨的字符用大的容器裝載後 * 再進行傳輸,這樣減少了傳輸的回合,提高效率 * */ //調用connection的getInputStream可以獲取服務器返回的字符流 InputStream inputStream = connection.getInputStream(); //調用InputStreamReader對象,可以把字節流轉換為字符流 InputStreamReader isr = new InputStreamReader(inputStream); //用BufferReader去裝載字符流 br = new BufferedReader(isr); //調用BufferedReader的方法,更便捷的獲取請求的內容 //定義一個字符串變量用來接收BufferedReader的readLine方法讀取的每一行數據 String line; StringBuffer stringBuffer = new StringBuffer(); int count = 0; while ((line = br.readLine()) != null) { //讀取的每一行數據都放在stringBuffer中 stringBuffer.append(line); /** * 5、對UI中已經定義的進度條進行更新,直接調用publishProgress方法 * 但是裡面的參數類型必須和AsyncTask中聲明的泛型一致,即Float */ count += line.length(); Integer value = (int) (count / (float) Total * 100); publishProgress(value); Thread.sleep(1000); } return stringBuffer.toString(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { e.printStackTrace(); } } //如果執行期間發生異常,則返回null return null; } /** * 3、復寫onPostExecute,其中它的參數值來源於doInBackground的返回值 * 該方法可以更新主線程的UI,把返回的內容直接顯示在主線程的TextView上 */ @Override protected void onPostExecute(String s) { tv.setText(s); Toast.makeText(UIActivity.this, "數據下載結束", Toast.LENGTH_SHORT).show(); } @Override protected void onProgressUpdate(Integer... values) { progressBar.setProgress(values[0]); } } }
AndroidManifest.xml
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.noodles.uipractice"> <uses-permission android:name="android.permission.INTERNET"> <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsrtl="true" android:theme="@style/AppTheme"> <activity android:name=".UIActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"> <category android:name="android.intent.category.LAUNCHER"> </category></action></intent-filter> </activity> </application> </uses-permission></manifest>
點擊前:
點擊後:
總結:AsyncTask是Android提供另一種異步信息處理機制,明確的說就是多線程間的通訊,有別於Handler機制地方,它是Handler的封裝所以在使用上面
更加的便捷,首先我們需要繼承該類,復寫裡面的方法,必須復寫就是doInBackground(Params),該方法會創建一個子線程去執行方法中代碼,所以一般用來
執行耗時的操作,比如下載文件。然後我們需要創建該子類的對象,並調用execute(Params)方法,其中參數Params由外部傳入,該參數會自動傳入oInBackground(Params)的參數,並且在AsyncTask的第一個泛型參數Params指定它的類型,第二泛型參數progress是指AsyncTask在doInBackground(Params)方法中可以調用publishProgress(progress),需要指定具體類型的值progress,系統會轉而調用onProgressUpdate(progress)同時傳入該數值,這個方法可以對主線程的UI進行更新,一般是用作更新進度條。第三個參數Result,是指doInBackground(Params)方法執行後需要返回一個值,接著系統會調用onPostExecute(Result),並把返回指傳入這個方法,這個方法是執行一些收尾工作,把信息反饋給用戶,比如更新主線程的UI,告訴用戶下載已經完成等。
FloatingActionButton增強版,一個按鈕跳出多個按鈕--第三方開源--FloatingActionButton,floatingactionbutton&
我的android學習經歷15,android學習經歷15利用Intent實現有返回結果的頁面跳轉 主要用的方法: (1)Intent的構造方法:intent(當前界面對
android 自定義圖片合集(自定義控件) 留守公司就剩下幾個人了。我沒有年假故還在堅守。廢話不多說,閒來無事。想練習一下自定義控件的應用以及學習圖片類操作以及處理
Android-Universal-Image-Loader (圖片異步加載緩存庫)的源碼解讀 前言: 在Android開發中,對於圖片的加載可以說是個老生常談的問題了,