導航:首頁 > 操作系統 > android中trycatch

android中trycatch

發布時間:2022-12-26 09:56:50

⑴ 如何在android的jni線程中實現回調

jni回調是指在c/c++代碼中調用java函數,當在c/c++的線程中執行回調函數時,會導致回調失敗。

其中一種在Android系統的解決方案是:

把c/c++中所有線程的創建,由pthread_create函數替換為由Java層的創建線程的函數AndroidRuntime::createJavaThread。

假設有c++函數:

[cpp] view plain
void *thread_entry(void *args)
{
while(1)
{
printf("thread running...\n");
sleep(1);
}

}

void init()
{
pthread_t thread;
pthread_create(&thread,NULL,thread_entry,(void *)NULL);
}

init()函數創建一個線程,需要在該線程中調用java類Test的回調函數Receive:

[cpp] view plain
public void Receive(char buffer[],int length){
String msg = new String(buffer);
msg = "received from jni callback:" + msg;
Log.d("Test", msg);
}

首先在c++中定義回調函數指針:

[cpp] view plain
//test.h
#include <pthread.h>
//function type for receiving data from native
typedef void (*ReceiveCallback)(unsigned char *buf, int len);

/** Callback for creating a thread that can call into the Java framework code.
* This must be used to create any threads that report events up to the framework.
*/
typedef pthread_t (* CreateThreadCallback)(const char* name, void (*start)(void *), void* arg);

typedef struct{
ReceiveCallback recv_cb;
CreateThreadCallback create_thread_cb;
}Callback;

再修改c++中的init和thread_entry函數:

[cpp] view plain
//test.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/wait.h>
#include <unistd.h>
#include "test.h"

void *thread_entry(void *args)
{
char *str = "i'm happy now";
Callback cb = NULL;
int len;
if(args != NULL){
cb = (Callback *)args;
}

len = strlen(str);
while(1)
{
printf("thread running...\n");
//invoke callback method to java
if(cb != NULL && cb->recv_cb != NULL){
cb->recv_cb((unsigned char*)str, len);
}
sleep(1);
}

}

void init(Callback *cb)
{
pthread_t thread;
//pthread_create(&thread,NULL,thread_entry,(void *)NULL);
if(cb != NULL && cb->create_thread_cb != NULL)
{
cb->create_thread_cb("thread",thread_entry,(void *)cb);
}
}

然後在jni中實現回調函數,以及其他實現:

[cpp] view plain
//jni_test.c
#include <stdlib.h>
#include <malloc.h>
#include <jni.h>
#include <JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"

#include "test.h"
#define RADIO_PROVIDER_CLASS_NAME "com/tonny/Test"

using namespace android;

static jobject mCallbacksObj = NULL;
static jmethodID method_receive;

static void (JNIEnv* env, const char* methodName) {
if (env->ExceptionCheck()) {
LOGE("An exception was thrown by callback '%s'.", methodName);
LOGE_EX(env);
env->ExceptionClear();
}
}

static void receive_callback(unsigned char *buf, int len)
{
int i;
JNIEnv* env = AndroidRuntime::getJNIEnv();
jcharArray array = env->NewCharArray(len);
jchar *pArray ;

if(array == NULL){
LOGE("receive_callback: NewCharArray error.");
return;
}

pArray = (jchar*)calloc(len, sizeof(jchar));
if(pArray == NULL){
LOGE("receive_callback: calloc error.");
return;
}

// buffer to jchar array
for(i = 0; i < len; i++)
{
*(pArray + i) = *(buf + i);
}
// buffer to jcharArray
env->SetCharArrayRegion(array,0,len,pArray);
//invoke java callback method
env->CallVoidMethod(mCallbacksObj, method_receive,array,len);
//release resource
env->DeleteLocalRef(array);
free(pArray);
pArray = NULL;

(env, __FUNCTION__);
}

static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg)
{
return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg);
}

static Callback mCallbacks = {
receive_callback,
create_thread_callback
};

static void jni_class_init_native
(JNIEnv* env, jclass clazz)
{
method_receive = env->GetMethodID(clazz, "Receive", "([CI)V");
}

static int jni_init
(JNIEnv *env, jobject obj)
{

if (!mCallbacksObj)
mCallbacksObj = env->NewGlobalRef(obj);

return init(&mCallbacks);
}

static const JNINativeMethod gMethods[] = {
{ "class_init_native", "()V", (void *)jni_class_init_native },
{ "native_init", "()I", (void *)jni_init },
};

static int registerMethods(JNIEnv* env) {

const char* const kClassName = RADIO_PROVIDER_CLASS_NAME;
jclass clazz;
/* look up the class */
clazz = env->FindClass(kClassName);
if (clazz == NULL) {
LOGE("Can't find class %s/n", kClassName);
return -1;
}
/* register all the methods */
if (env->RegisterNatives(clazz,gMethods,sizeof(gMethods)/sizeof(gMethods[0])) != JNI_OK)
{
LOGE("Failed registering methods for %s/n", kClassName);
return -1;
}
/* fill out the rest of the ID cache */
return 0;
}

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = -1;
LOGI("Radio JNI_OnLoad");
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed/n");
goto fail;
}

if(env == NULL){
goto fail;
}
if (registerMethods(env) != 0) {
LOGE("ERROR: PlatformLibrary native registration failed/n");
goto fail;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
fail:
return result;
}

jni的Android.mk文件中共享庫設置為:

[cpp] view plain
LOCAL_SHARED_LIBRARIES := liblog libcutils libandroid_runtime libnativehelper

最後再實現Java中的Test類:

[java] view plain
//com.tonny.Test.java

public class Test {

static{
try {
System.loadLibrary("test");
class_init_native();

} catch(UnsatisfiedLinkError ule){
System.err.println("WARNING: Could not load library libtest.so!");
}

}

public int initialize() {
return native_radio_init();
}

public void Receive(char buffer[],int length){
String msg = new String(buffer);
msg = "received from jni callback" + msg;
Log.d("Test", msg);
}

protected static native void class_init_native();

protected native int native_init();

}

⑵ android 的try catch 具體能處理什麼問題 簡單介紹 給個簡單的例子

try{
//代碼區
}catch(Exceptione){
//異常處理
}
代碼區如果有錯誤,就會返回所寫異常的處理。

首先要清楚,如果沒有try的話,出現異常會導致程序崩潰。
而try則可以保證程序的正常運行下去,比如說:
try{
inti=1/0;
}catch(Exceptione){
........
}
一個計算的話,如果除數為0,則會報錯,如果沒有try的話,程序直接崩潰。用try的話,則可以讓程序運行下去,並且輸出為什麼出錯!
trycatch是捕捉try部分的異常,當你沒有trycatch的時候,如果出現異常則程序報錯,加上trycatch,出現異常程序正常運行,只是把錯誤信息存儲到Exception里,所以catch是用來提取異常信息的,你可以在Catch部分加上一句System.out.println(e.ToString());,如果出現異常可以把異常列印出來

⑶ android中的try catch不執行

說明代碼寫的有問題,建議debug調式運行,異常都會在logcat中輸出的。
找到Logcat視圖的方式:
1. Eclipse 點擊 Window。
2. Show View會出來一個對話框。
3. 點擊Ok按鈕時,會在控制台窗口出現LogCat視圖。

⑷ android開發怎麼會出現資料庫錯誤

1. 異常機制
1.1 異常機制是指當程序出現錯誤後,程序如何處理。具體來說,異常機制提供了程序退出的安全通道。當出現錯誤後,程序執行的流程發生改變,程序的控制權轉移到異常處理器。
1.2 傳統的處理異常的辦法是,函數返回一個特殊的結果來表示出現異常(通常這個特殊結果是大家約定俗稱的),調用該函數的程序負責檢查並分析函數返回的結果。這樣做有如下的弊端:例如函數返回-1代表出現異常,但是如果函數確實要返回-1這個正確的值時就會出現混淆;可讀性降低,將程序代碼與處理異常的代碼混爹在一起;由調用函數的程序來分析錯誤,這就要求客戶程序員對庫函數有很深的了解。
1.3 異常處理的流程
1.3.1 遇到錯誤,方法立即結束,並不返回一個值;同時,拋出一個異常對象
1.3.2 調用該方法的程序也不會繼續執行下去,而是搜索一個可以處理該異常的異常處理器,並執行其中的代碼
2 異常的分類
2.1 異常的分類
2.1.1 異常的繼承結構:基類為Throwable,Error和Exception繼承Throwable,RuntimeException和 IOException等繼承Exception,具體的RuntimeException繼承RuntimeException。
2.1.2 Error和RuntimeException及其子類成為未檢查異常(unchecked),其它異常成為已檢查異常(checked)。
2.2 每個類型的異常的特點
2.2.1 Error體系 Error類體系描述了Java運行系統中的內部錯誤以及資源耗盡的情形。應用程序不應該拋出這種類型的對象(一般是由虛擬機拋出)。如果出現這種錯誤,除了盡力使程序安全退出外,在其他方面是無能為力的。所以,在進行程序設計時,應該更關注Exception體系。
2.2.2 Exception體系 Exception體系包括RuntimeException體系和其他非RuntimeException的體系
2.2.2.1 RuntimeException RuntimeException體系包括錯誤的類型轉換、數組越界訪問和試圖訪問空指針等等。處理RuntimeException的原則是:如果出現 RuntimeException,那麼一定是程序員的錯誤。例如,可以通過檢查數組下標和數組邊界來避免數組越界訪問異常。
2.2.2.2 其他(IOException等等)這類異常一般是外部錯誤,例如試圖從文件尾後讀取數據等,這並不是程序本身的錯誤,而是在應用環境中出現的外部錯誤。
2.3 與C++異常分類的不同
2.3.1 其實,Java中RuntimeException這個類名起的並不恰當,因為任何異常都是運行時出現的。(在編譯時出現的錯誤並不是異常,換句話說,異常就是為了解決程序運行時出現的的錯誤)。
2.3.2 C++中logic_error與Java中的RuntimeException是等價的,而runtime_error與Java中非RuntimeException類型的異常是等價的。
3 異常的使用方法
3.1 聲明方法拋出異常
3.1.1 語法:throws(略)
3.1.2 為什麼要聲明方法拋出異常?方法是否拋出異常與方法返回值的類型一樣重要。假設方法拋出異常確沒有聲明該方法將拋出異常,那麼客戶程序員可以調用這個方法而且不用編寫處理異常的代碼。那麼,一旦出現異常,那麼這個異常就沒有合適的異常控制器來解決。
3.1.3 為什麼拋出的異常一定是已檢查異常? RuntimeException與Error可以在任何代碼中產生,它們不需要由程序員顯示的拋出,一旦出現錯誤,那麼相應的異常會被自動拋出。而已檢查異常是由程序員拋出的,這分為兩種情況:客戶程序員調用會拋出異常的庫函數(庫函數的異常由庫程序員拋出);客戶程序員自己使用throw語句拋出異常。遇到Error,程序員一般是無能為力的;遇到RuntimeException,那麼一定是程序存在邏輯錯誤,要對程序進行修改(相當於調試的一種方法);只有已檢查異常才是程序員所關心的,程序應該且僅應該拋出或處理已檢查異常。
3.1.4 注意:覆蓋父類某方法的子類方法不能拋出比父類方法更多的異常,所以,有時設計父類的方法時會聲明拋出異常,但實際的實現方法的代碼卻並不拋出異常,這樣做的目的就是為了方便子類方法覆蓋父類方法時可以拋出異常。
3.2 如何拋出異常
3.2.1 語法:throw(略)
3.2.2 拋出什麼異常?對於一個異常對象,真正有用的信息時異常的對象類型,而異常對象本身毫無意義。比如一個異常對象的類型是 ClassCastException,那麼這個類名就是唯一有用的信息。所以,在選擇拋出什麼異常時,最關鍵的就是選擇異常的類名能夠明確說明異常情況的類。
3.2.3 異常對象通常有兩種構造函數:一種是無參數的構造函數;另一種是帶一個字元串的構造函數,這個字元串將作為這個異常對象除了類型名以外的額外說明。
3.2.4 創建自己的異常:當Java內置的異常都不能明確的說明異常情況的時候,需要創建自己的異常。需要注意的是,唯一有用的就是類型名這個信息,所以不要在異常類的設計上花費精力。
3.3 捕獲異常如果一個異常沒有被處理,那麼,對於一個非圖形界面的程序而言,該程序會被中止並輸出異常信息;對於一個圖形界面程序,也會輸出異常的信息,但是程序並不中止,而是返回用戶界面處理循環中。
3.3.1 語法:try、catch和finally(略)控制器模塊必須緊接在try塊後面。若擲出一個異常,異常控制機制會搜尋參數與異常類型相符的第一個控制器隨後它會進入那個catch 從句,並認為異常已得到控制。一旦catch 從句結束對控制器的搜索也會停止。 3.3.1.1 捕獲多個異常(注意語法與捕獲的順序)(略)
3.3.1.2 finally的用法與異常處理流程(略)
3.3.2 異常處理做什麼?對於Java來說,由於有了垃圾收集,所以異常處理並不需要回收內存。但是依然有一些資源需要程序員來收集,比如文件、網路連接和圖片等資源。
3.3.3 應該聲明方法拋出異常還是在方法中捕獲異常?原則:捕捉並處理哪些知道如何處理的異常,而傳遞哪些不知道如何處理的異常
3.3.4 再次拋出異常
3.3.4.1 為什麼要再次拋出異常?在本級中,只能處理一部分內容,有些處理需要在更高一級的環境中完成,所以應該再次拋出異常。這樣可以使每級的異常處理器處理它能夠處理的異常。
3.3.4.2 異常處理流程對應與同一try塊的catch塊將被忽略,拋出的異常將進入更高的一級。
4 關於異常的其他問題
4.1 過度使用異常首先,使用異常很方便,所以程序員一般不再願意編寫處理錯誤的代碼,而僅僅是簡簡單單的拋出一個異常。這樣做是不對的,對於完全已知的錯誤,應該編寫處理這種錯誤的代碼,增加程序的魯棒性。另外,異常機制的效率很差。
4.2 將異常與普通錯誤區分開對於普通的完全一致的錯誤,應該編寫處理這種錯誤的代碼,增加程序的魯棒性。只有外部的不能確定和預知的運行時錯誤才需要使用異常。
4.3 異常對象中包含的信息一般情況下,異常對象唯一有用的信息就是類型信息。但使用異常帶字元串的構造函數時,這個字元串還可以作為額外的信息。調用異常對象的getMessage()、toString()或者printStackTrace()方法可以分別得到異常對象的額外信息、類名和調用堆棧的信息。並且後一種包含的信息是前一種的超集。
請對照分析你的錯誤類型

⑸ android怎麼阻止完成try和catch函數

可以用以下兩種方法試試:
1,label懂得自己更新,label.Text=...不必放在panel1_Paint()裡面。panel1_Paint應只做和畫圖相關的事情。
2,用int.TryParse()而不是Convert.ToInt32(),int.TryParse()不成功的時候也不會拋出異常。當它不成功可以用一個默認值。

⑹ android中google有一個方法可以替代 Thread.sleep()方法來著。它不需要try catch,叫啥

如果是想延時一下,在處理業務邏輯的話,可以使用handler類提供的方法:handler.postDelayed()直接延時操作

⑺ androidstudio中怎麼捕獲異常

//可以使用try catch finally語句來捕獲異常。

//代碼格式:

try{
//如果要捕獲異常,需要將代碼放置在這try的代碼塊范圍內
}catch(IOException ex){//異常范圍IOException 以及它的派生類異常
//此處編寫發生 IOException 或其派生類異常時處理方案
}catch(Exception ex){//異常范圍Exception 以及它的派生類異常
//此處編寫發生Exception 或其派生類異常時處理方案
}finally{
//此處無論上方的代碼中是否出現了異常、return語句,這里必定執行。
}
/*
try catch語句至少需要有一個catch,卻可以同時有多個catch。
其中catch語句塊的異常范圍從上到下順序書寫時應當從小范圍到達范圍,如果將Exception的catch與IOException的catch位置對換,那麼永遠不會執行IOException的catch塊的代碼
finally語句代碼塊是可選的。可以有它,也可以不使用它,具體是否啟用它需要根據業務邏輯決定
*/

⑻ Android編程,怎樣讓整個activity都運行在try-catch中,總是因為點小錯誤就閃退

Activity本身沒錯,錯的是你的業務邏輯,你把邏輯抽出到Service類,再調用,加上try捕捉吧。
你的想法有點偏。
不記得了,在Application的實例裡面可以設置未捕捉異常的處理,這也可以。

⑼ android代碼,我無論如何也無法在主線程中等待dialog的出現

自己看看書把,在子線程中發消息出來,然後在主線程接受到消息的時候彈出dialog

⑽ android studio 怎麼快速加try catch

快捷鍵: Ctrl + Alt + S
1.選擇try catch
2.選擇try finally
3.選擇try catch finally

閱讀全文

與android中trycatch相關的資料

熱點內容
javatomcat圖片 瀏覽:415
程序員生產智能創意 瀏覽:65
匯和銀行app怎麼登錄 瀏覽:381
騰訊伺服器如何上傳源碼 瀏覽:739
單片機的原理概述 瀏覽:508
火控pdf 瀏覽:267
如何復制雲伺服器centos環境 瀏覽:984
債權pdf 瀏覽:301
紅色番字的app怎麼下載 瀏覽:876
雲伺服器流程教課 瀏覽:702
中國農業銀行app怎麼沒有網 瀏覽:997
幾率表演算法 瀏覽:902
程序員理工科 瀏覽:708
企業郵箱登錄收件伺服器地址 瀏覽:558
計算機思維與演算法設計的重要性 瀏覽:664
linux刷新磁碟命令 瀏覽:76
我的世界如何查看伺服器種子pc 瀏覽:284
linuxlamp編譯安裝 瀏覽:609
枚舉演算法ppt 瀏覽:184
cmd查看進程命令 瀏覽:956