![Android移動應(yīng)用開發(fā)-線程間的通信與異步機(jī)制_第1頁](http://file4.renrendoc.com/view/eade5fbee27c0b8f5af92f48f11d48ef/eade5fbee27c0b8f5af92f48f11d48ef1.gif)
![Android移動應(yīng)用開發(fā)-線程間的通信與異步機(jī)制_第2頁](http://file4.renrendoc.com/view/eade5fbee27c0b8f5af92f48f11d48ef/eade5fbee27c0b8f5af92f48f11d48ef2.gif)
![Android移動應(yīng)用開發(fā)-線程間的通信與異步機(jī)制_第3頁](http://file4.renrendoc.com/view/eade5fbee27c0b8f5af92f48f11d48ef/eade5fbee27c0b8f5af92f48f11d48ef3.gif)
![Android移動應(yīng)用開發(fā)-線程間的通信與異步機(jī)制_第4頁](http://file4.renrendoc.com/view/eade5fbee27c0b8f5af92f48f11d48ef/eade5fbee27c0b8f5af92f48f11d48ef4.gif)
![Android移動應(yīng)用開發(fā)-線程間的通信與異步機(jī)制_第5頁](http://file4.renrendoc.com/view/eade5fbee27c0b8f5af92f48f11d48ef/eade5fbee27c0b8f5af92f48f11d48ef5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Android移動應(yīng)用開發(fā)
010302040706認(rèn)識Android列表與適配器菜單與對話框設(shè)計UI控件設(shè)計設(shè)計用戶界面創(chuàng)建Android項目Android本地存儲書目錄140911BroadcastReceiver與廣播通信Service與后臺服務(wù)設(shè)計ContentProvider與應(yīng)用間數(shù)據(jù)共享網(wǎng)絡(luò)連接與管理05Activity與Fragment08131210線程間的通信與異步機(jī)制Android性能分析與測試
線程間的通信與異步機(jī)制章目錄8.1應(yīng)用程序的消息處理機(jī)制8.2異步任務(wù)封裝類8.1.1線程與單線程模型應(yīng)用程序啟動時,系統(tǒng)會創(chuàng)建一個名為“main”的主線程。它是應(yīng)用程序與AndroidUI組件包(android.widget包和android.view包)進(jìn)行交互的線程,負(fù)責(zé)把事件分發(fā)給相應(yīng)的用戶界面。因此,主線程有時也被叫作UI線程。系統(tǒng)并不會為每個組件的實例都創(chuàng)建單獨的線程。對系統(tǒng)回調(diào)進(jìn)行響應(yīng)的方法總是運(yùn)行在UI線程中。如果應(yīng)用程序在與用戶交互的同時需要執(zhí)行繁重的任務(wù),則單線程模型可能會導(dǎo)致運(yùn)行性能低,甚至?xí)枞麄€UI線程。一旦UI線程被阻塞,所有事件都不能被分發(fā),包括屏幕繪圖事件。Andoid的UI組件包并不是線程安全的。因此不允許從工作線程中操作UI—只能從UI線程中操作用戶界面。8.1.1線程與單線程模型例如,下面的代碼試圖通過loadImage()方法更新ImageView的內(nèi)容。publicclassTheadActivity1extendsActivity{@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);loadImage("/img/baidu_logo.gif",R.id.imageView1);}privateHandlerhandler=newHandler();privatevoidloadImage(finalStringurl,finalintid){handler.post(newRunnable(){publicvoidrun(){Drawabledrawable=null;try{drawable=Drawable.createFromStream(newURL(url).openStream(),"image.gif");} catch(IOExceptione){Log.d("test",e.getMessage());}if(drawable==null){Log.d("LWY","nulldrawable");} else{Log.d("LWY","notnulldrawable");}//為了測試緩存而模擬的網(wǎng)絡(luò)延時SystemClock.sleep(2000);//下面代碼破壞了單線程規(guī)則,異常會發(fā)生((ImageView)findViewById(id)).setImageDrawable(drawable);}});}}8.1.1線程與單線程模型Andoid的單線程模型必須遵守兩個規(guī)則。不要阻塞UI線程。不要在UI線程之外訪問Andoid的UI組件包。Android提供了很多便于管理線程的類:Looper用于在一個線程中運(yùn)行一個消息循環(huán),Handler用于處理消息,HandlerThread用于使用一個消息循環(huán)啟用一個線程。Android提供的異步任務(wù)類AsyncTask簡化了一些工作線程和UI交互的操作。8.1.2Handler消息傳遞機(jī)制Android的消息處理有3個核心類:Looper、Handler和Message。為一個線程建立消息循環(huán)的基本步驟為以下4步。初始化Looper。綁定Handler到CustomThread實例的Looper對象。定義處理消息的方法handleMessage()。啟動消息循環(huán)。LooperLooper在Android中被設(shè)計用來使一個普通線程變成Looper線程。所謂Looper線程就是循環(huán)工作的線程。Looper有以下幾個重要方法。Looper.prepare()Looper.loop()Looper.prepareMainLooper()Looper.getMainLooper()Looper.quit()/Looper.quitSafely()8.1.2Handler消息傳遞機(jī)制下面的代碼是使用Looper類創(chuàng)建Looper線程的典型應(yīng)用方法。@Overridepublicvoidrun(){Looper.prepare();mHandler=newHandler(){publicvoidhandleMessage(Messagemsg){//消息事件處理}};Looper.loop();}}通過調(diào)用Looper.loop()方法,Looper線程開始工作。它不斷從自己的消息隊列中取出隊頭的消息(也叫“任務(wù)”)執(zhí)行。8.1.2Handler消息傳遞機(jī)制HandlerHandler主要負(fù)責(zé)向消息隊列中添加消息和處理消息(只處理由自己發(fā)出的消息),即通知消息隊列要執(zhí)行一個任務(wù)[sendMessage()方法],并在輪詢到自己的時候執(zhí)行該任務(wù)[handleMessage()方法],整個過程是異步的。下面的代碼演示了在Thread子類中加入Handler實現(xiàn)消息隊列功能的方法。publicclassLooperThreadextendsThread{privateHandlerhandler;@Overridepublicvoidrun(){Looper.prepare();handler=newHandler();Looper.loop();}}8.1.2Handler消息傳遞機(jī)制通過Handler發(fā)送的Message對象有如下特點。message.target為該Handler對象,這確保了Looper執(zhí)行到該Message對象時能找到處理它的Handler,即loop()方法中的代碼。message.target為該Handler對象,這確保了Looper執(zhí)行到該Message對象時能找到處理它的Handler,即loop()方法中的代碼。post()方法發(fā)出的Message對象,其回調(diào)為Runnable對象。msg.target.dispatchMessage(msg);8.1.2Handler消息傳遞機(jī)制Handler擁有以下兩個重要的特點。Handler可以在任意線程中發(fā)送消息,這些消息會被添加到關(guān)聯(lián)的消息隊列中,如左圖所示。Handler在它關(guān)聯(lián)的Looper線程中處理消息,如右圖所示。8.1.2Handler消息傳遞機(jī)制Handler的這兩個特點解決了Android不能在其他非主線程中更新UI的問題。Handler的解決方案就是在Activity中創(chuàng)建Handler并將其引用傳遞給工作線程,工作線程執(zhí)行完任務(wù)后使用Handler發(fā)送消息并通知Activity更新UI,如圖所示。8.1.2Handler消息傳遞機(jī)制Message和MessageQueueMessage是線程之間傳遞信息的載體,包含對消息的描述和任意的數(shù)據(jù)對象。Message中包含兩個額外的int字段(Message.arg1和Message.arg2)和一個Object字段,并通過Message.what來標(biāo)識信息,以便用不同方式處理Message。MessageQueue是用來容納Message的,其中的Message是由Looper分發(fā)的。Message不能直接添加到MessageQueue中,而要通過與Looper關(guān)聯(lián)的Handler添加。應(yīng)用程序一啟動UI線程(也就是主線程)就會有一個MessageQueue,而如果是自己另外啟動的一個子線程就不會有MessageQueue對象。8.1.3Thread+Handler+Message應(yīng)用下面介紹使用消息處理機(jī)制實現(xiàn)異步任務(wù)的方法。首先,在創(chuàng)建線程池的類(如MainActivity)的構(gòu)造過程中實例化Handler對象,并將該對象存儲在全局變量中。例如:privatePhotoManager(){…//定義附加到UI線程的處理程序?qū)ο骽andler=newHandler(Looper.getMainLooper()){…/**handleMessage()方法中定義用于處理消息的響應(yīng)事件*theHandlerreceivesanewMessagetoprocess*/@OverridepublicvoidhandleMessage(MessageinputMessage){//從PhotoTask中獲取消息傳遞過來的圖像信息PhotoTaskphotoTask=(PhotoTask)inputMessage.obj;…}…}}8.1.3Thread+Handler+Message應(yīng)用接下來,將任務(wù)對象和狀態(tài)代碼傳遞給實例化Handler的對象。例如,下面是一個在后臺線程上運(yùn)行的Runnable,它將對Bitmap進(jìn)行解碼并將其存儲在其父對象PhotoTask中。Runnable還會存儲狀態(tài)代碼DECODE_STATE_COMPLETED。//將photo解碼為BitmapsclassPhotoDecodeRunnableimplementsRunnable{…PhotoDecodeRunnable(PhotoTaskdownloadTask){photoTask=downloadTask;}…//獲取下載的字節(jié)數(shù)組byte[]imageBuffer=photoTask.getByteBuffer();…//執(zhí)行線程任務(wù)publicvoidrun(){…//解碼字節(jié)數(shù)組returnBitmap=BitmapFactory.decodeByteArray(imageBuffer,0,imageBuffer.length,bitmapOptions);…//給ImageView設(shè)置BitmapphotoTask.setImage(returnBitmap);//報告解碼完成photoTask.handleDecodeState(DECODE_STATE_COMPLETED);…}…}8.1.3Thread+Handler+Message應(yīng)用其中的PhotoTask對象中存放著對解碼數(shù)據(jù)以及將顯示該數(shù)據(jù)的View對象的引用。publicclassPhotoTask{…//獲取創(chuàng)建線程池對象的Handle對象photoManager=PhotoManager.getInstance();…publicvoidhandleDecodeState(intstate){intoutState;//將解碼狀態(tài)轉(zhuǎn)換為完成狀態(tài)switch(state){casePhotoDecodeRunnable.DECODE_STATE_COMPLETED:outState=PhotoManager.TASK_COMPLETE;break;…}…//調(diào)用狀態(tài)處理方法handleState(outState);}…//將狀態(tài)傳遞給PhotoManagervoidhandleState(intstate){/**將此任務(wù)的句柄和當(dāng)前狀態(tài)傳遞給創(chuàng)建線程池的類*/photoManager.handleState(this,state);}…}8.1.3Thread+Handler+Message應(yīng)用PhotoManager對象從PhotoTask對象接收狀態(tài)代碼和PhotoTask對象的句柄。publicclassPhotoManager{…//處理來自任務(wù)的狀態(tài)消息publicvoidhandleState(PhotoTaskphotoTask,intstate){switch(state){…//圖像下載并完成解碼后的任務(wù)處理caseTASK_COMPLETE:MessagecompleteMessage=handler.obtainMessage(state,photoTask);completeMessage.sendToTarget();break;…}…}}default:/**從UI傳遞其他消息*/super.handleMessage(inputMessage);}…}…}…}privatePhotoManager(){……h(huán)andler=newHandler(Looper.getMainLooper()){@OverridepublicvoidhandleMessage(MessageinputMessage){//獲取消息傳遞的對象PhotoTaskphotoTask=(PhotoTask)inputMessage.obj;//獲取任務(wù)中的ImageView對象PhotoViewlocalView=photoTask.getPhotoView();…switch(inputMessage.what){…//完成解碼caseTASK_COMPLETE:/**將Bitmap顯示在View上*/localView.setImageBitmap(photoTask.getImage());break;…8.1.3Thread+Handler+Message應(yīng)用最后,通過Handler.handleMessage()方法檢查每一條傳入Message的狀態(tài)代碼。任務(wù)8.1實現(xiàn)音樂播放器本地音樂的異步加載功能【任務(wù)介紹】1.任務(wù)描述在第6章任務(wù)6.1的基礎(chǔ)上,實現(xiàn)音樂播放器本地音樂的異步加載功能。2.運(yùn)行結(jié)果本任務(wù)運(yùn)行結(jié)果如圖所示。章目錄8.1應(yīng)用程序的消息處理機(jī)制8.2異步任務(wù)封裝類8.2.1HandlerThread先分析HandlerThread的源代碼。publicclassHandlerThreadextendsThread{intmPriority;//線程執(zhí)行優(yōu)先級intmTid=-1;//調(diào)用線程的標(biāo)識符LoopermLooper;//線程內(nèi)部的Looper對象,一個線程只有一個Looper對象private@NullableHandlermHandler;//與Looper綁定的Handler對象publicHandlerThread(Stringname){super(name);//設(shè)置優(yōu)先級mPriority=Process.THREAD_PRIORITY_DEFAULT;}publicHandlerThread(Stringname,intpriority){super(name);mPriority=priority;}//Looper開啟循環(huán)前調(diào)用,可在子類中按需覆寫實現(xiàn)protectedvoidonLooperPrepared(){}
8.2.1HandlerThread@Overridepublicvoidrun(){//返回調(diào)用線程的標(biāo)識符mTid=Process.myTid();//初始化線程本地變量LooperLooper.prepare();synchronized(this){//從Looper中獲取本線程的Looper對象mLooper=Looper.myLooper();notifyAll();//喚醒線程}Process.setThreadPriority(mPriority);onLooperPrepared();//回調(diào)方法,在循環(huán)之前,可在子類中按需覆寫實現(xiàn)Looper.loop();mTid=-1;}//返回Looper對象publicLoopergetLooper(){//如果線程不是可用狀態(tài),則返回nullif(!isAlive()){returnnull;}8.2.1HandlerThread
//如果線程被啟動了,但是mLooper對象還沒有被初始化,則讓線程進(jìn)入等待狀態(tài),//直到mLooper對象被初始化后線程被喚醒synchronized(this){while(isAlive()&&(mLooper==null)){try{wait();}catch(InterruptedExceptione){}}}returnmLooper;}@NonNull//懶加載初始化Handler的單例對象,該Handler與此線程獲取的Looper進(jìn)行綁定publicHandlergetThreadHandler(){if(mHandler==null){mHandler=newHandler(getLooper());}returnmHandler;}8.2.1HandlerThread//退出,執(zhí)行的是looper.quit()方法,其實執(zhí)行的是Looper中的MessageQueue.quit()方法publicbooleanquit(){Looperlooper=getLooper();if(looper!=null){looper.quit();returntrue;}returnfalse;}//同上述方法,執(zhí)行的是MessageQueue.quit()方法publicbooleanquitSafely(){Looperlooper=getLooper();if(looper!=null){looper.quitSafely();returntrue;}returnfalse;}//返回調(diào)用線程的標(biāo)識符publicintgetThreadId(){returnmTid;}}8.2.1HandlerThread通過分析源代碼可以發(fā)現(xiàn)以下幾點。HandlerThread繼承Thread,所以它的本質(zhì)是線程的一種實現(xiàn)。HandlerThread內(nèi)部有一個Looper對象,在線程啟動的時候,會初始化線程本地變量Looper。HandlerThread內(nèi)部有Handler對象,但采用的是懶加載的單例,在使用之前并未進(jìn)行初始化。在調(diào)用getThreadHandler()方法和getLooper()方法之前,必須確保線程已經(jīng)啟動了[調(diào)用start()方法],否則線程會進(jìn)入等待狀態(tài),直到在run()方法內(nèi)部的mLooper對象被賦值。在Looper開啟循環(huán)[調(diào)用loop()方法]之前,會執(zhí)行onLooperPrepared()方法,它默認(rèn)是一個空實現(xiàn),可在子類中按需覆寫實現(xiàn)。quit()方法和quitSafely()方法調(diào)用的是Looper對象的相應(yīng)方法,其實最終調(diào)用的都是Looper內(nèi)部MessageQueue的quit()方法。HandlerThread只是把線程和Looper進(jìn)行簡單的封裝,剩下的很多操作和異步消息處理機(jī)制是一樣的。8.2.1HandlerThread下面是一個使用HandlerThread下載圖片集的示例。publicclassHandlerThreadActivityextendsAppCompatActivity{//圖片地址集合privateStringurl[]={"/20160903083245762",…};privateImageViewimageView;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler_thread);imageView=(ImageView)findViewById(R.id.image);//創(chuàng)建異步HandlerThreadHandlerThreadhandlerThread=newHandlerThread("downloadImage");//必須先開啟線程handlerThread.start();//子線程Handler,用于異步下載圖片HandlerchildHandler=newHandler(handlerThread.getLooper(),newChildCallback());for(inti=0;i<url.length;i++){childHandler.sendEmptyMessageDelayed(i,1000*i);//每秒更新一張圖片}}8.2.1HandlerThread/***該Callback運(yùn)行于子線程*/classChildCallbackimplementsHandler.Callback{@OverridepublicbooleanhandleMessage(Messagemessage){//在子線程中進(jìn)行網(wǎng)絡(luò)請求Bitmapbitmap=downloadUrlBitmap(url[message.what]);ImageModelimageModel=newImageModel();imageModel.url=url[message.what];imageModel.bitmap=bitmap;Messagemsg=newMessage();msg.what=message.what;msg.obj=imageModel;mUIHandler.sendMessage(msg);//通知主線程更新UIreturnfalse;}}privateBitmapdownloadUrlBitmap(StringurlString){HttpURLConnectionurlConnection=null;BufferedInputStreamin=null;Bitmapbitmap=null;8.2.1HandlerThreadtry{finalURLurl=newURL(urlString);urlConnection=(HttpURLConnection)url.openConnection();in=newBufferedInputStream(urlConnection.getInputStream(),8*1024);bitmap=BitmapFactory.decodeStream(in);}catch(IOExceptione){e.printStackTrace();}finally{if(urlConnection!=null){urlConnection.disconnect();}try{if(in!=null){in.close();}}catch(IOExceptione){e.printStackTrace();}}returnbitmap;}/***用于更新UI*/privateHandlermUIHandler=newHandler(){@OverridepublicvoidhandleMessage(Messagemsg){ImageModelmodel=(ImageModel)msg.obj;imageView.setImageBitmap(model.bitmap);}};
classImageModel{Stringurl;Bitmapbitmap;ImageModel(){}}}8.2.2AsyncTaskAsyncTask是抽象類,在AsyncTask中定義了3種泛型類型:Params對應(yīng)doInBackground()方法
的參數(shù)類型。AProgress對應(yīng)onProgressUpdate()方法的參數(shù)類型,其顯示后臺
任務(wù)執(zhí)行的百分比。BResult對應(yīng)onPostExecute()方法的參數(shù)類型,是后臺執(zhí)行任務(wù)最終返回的結(jié)果,例如String。C8.2.2AsyncTaskAsyncTask執(zhí)行的每一步都對應(yīng)一個回調(diào)方法,這些方法不應(yīng)該由應(yīng)用程序調(diào)用,開發(fā)者需要做的就是實現(xiàn)這些方法。首先子類化AsyncTask,然后實現(xiàn)AsyncTask中定義的下面一個或幾個方法。-÷×+onPreExecute()方法執(zhí)行預(yù)處理。doInBackground()方法在onPreExecute()方法執(zhí)行后馬上自動執(zhí)行,后臺進(jìn)程執(zhí)行的具體計算在這里實現(xiàn)。注意:在doInBackground()方法中不能直接操作UI。onProgressUpdate()方法運(yùn)行于UI線程。onPostExecute()方法運(yùn)行于UI線程,相當(dāng)于Handler處理UI的方式。8.2.2AsyncTask為了正確地使用AsyncTask類,必須遵守以下幾條準(zhǔn)則。312AsyncTask的實例必須在UI線程中創(chuàng)建。execute()方法必須在UI線程中調(diào)用。不要手動地調(diào)用onPreExecute()、onPostExecute()、doInBackground()和onProgressUpdate()這幾個方法。注意,當(dāng)Activity重新創(chuàng)建時(屏幕旋轉(zhuǎn)/Activity被意外銷毀后恢復(fù)),之前運(yùn)行的AsyncTask(非靜態(tài)的
內(nèi)部類)持有的之前Activity引用已無效。8.2.2AsyncTask下面的示例演示了使用AsyncTask實現(xiàn)網(wǎng)絡(luò)下載的方法。publicclassMainActivityextendsAppCompatActivity{privatestaticfinalStringFILE_NAME="test.pdf";//下載文件的名稱privatestaticfinalStringPDF_URL="http://***/AsyncTask.pdf";privateProgressBarmProgressBar;privateButtonmDownloadBtn;privateTextViewmStatus;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();setListener();}privatevoidinitView(){mProgressBar=(ProgressBar)findViewById(R.gressBar);mDownloadBtn=(Button)findViewById(R.id.download);mStatus=(TextView)findViewById(R.id.status);}8.2.2AsyncTaskprivatevoidsetListener(){mDownloadBtn.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){//AsyncTask實例必須在主線程創(chuàng)建DownloadAsyncTaskasyncTask=newDownloadAsyncTask();asyncTask.execute(PDF_URL);}});}privateclassDownloadAsyncTaskextendsAsyncTask<String,Integer,Boolean>{privateStringmFilePath;//下載文件的保存路徑@OverrideprotectedBooleandoInBackground(String…params){if(params!=null&¶ms.length>0){StringpdfUrl=params[0];try{URLurl=newURL(pdfUrl);URLConnectionurlConnection=url.openConnection();InputStreamin=urlConnection.getInputStream();intcontentLength=urlConnection.getContentLength();
8.2.2AsyncTask//獲取內(nèi)容總長度mFilePath=Environment.getExternalStorageDirectory()+File.separator+FILE_NAME;//若存在同名文件則刪除FilepdfFile=newFile(mFilePath);if(pdfFile.exists()){booleanresult=pdfFile.delete();if(!result){returnfalse;}}
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 深信服智慧校園云機(jī)房解決方案
- 2025年山東省職教高考《語文》核心考點必刷必練試題庫(含答案)
- 《現(xiàn)代康旅產(chǎn)業(yè)概論》期末參考試題庫及答案
- 《工程招投標(biāo)與合同管理》參考試題庫(含答案)
- 2025年武夷山職業(yè)學(xué)院高職單招語文2018-2024歷年參考題庫頻考點含答案解析
- 2025年新疆輕工職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測試近5年??及鎱⒖碱}庫含答案解析
- 2025年晉中職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試近5年??及鎱⒖碱}庫含答案解析
- 部編版語文五年級下冊《快樂讀書吧》精美課件
- 滬教版(上海)七年級地理第一學(xué)期中國區(qū)域篇(上)1.3《青藏高原地區(qū)》聽課評課記錄
- 幼兒園中班秋季活動策劃方案五篇
- 2025版茅臺酒出口業(yè)務(wù)代理及銷售合同模板4篇
- 2025年N1叉車司機(jī)考試試題(附答案)
- 《醫(yī)院財務(wù)分析報告》課件
- 2024年考研政治試題及答案
- 2025年初級社會工作者綜合能力全國考試題庫(含答案)
- 2024年濰坊護(hù)理職業(yè)學(xué)院單招職業(yè)適應(yīng)性測試題庫附答案
- 《鉗工基本知識》課件
- 2022-2023學(xué)年五年級數(shù)學(xué)春季開學(xué)摸底考(四)蘇教版
- 【螞蟻?!?024中國商業(yè)醫(yī)療險發(fā)展研究藍(lán)皮書
- 授信審批部工作計劃及思路
- 財務(wù)管理學(xué)(第10版)課件 第3章 財務(wù)分析
評論
0/150
提交評論