类com.facebook.react.bridge.GuardedAsyncTask源码实例Demo

下面列出了怎么用com.facebook.react.bridge.GuardedAsyncTask的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: react-native-tcp-socket   文件: TcpSocketModule.java
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("unused")
@ReactMethod
public void write(@NonNull final Integer cId, @NonNull final String base64String, @Nullable final Callback callback) {
    new GuardedAsyncTask<Void, Void>(mReactContext.getExceptionHandler()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            TcpSocketClient socketClient = socketClients.get(cId);
            if (socketClient == null) {
                return;
            }
            try {
                socketClient.write(Base64.decode(base64String, Base64.NO_WRAP));
                if (callback != null) {
                    callback.invoke();
                }
            } catch (IOException e) {
                if (callback != null) {
                    callback.invoke(e.toString());
                }
                onError(cId, e.toString());
            }
        }
    }.executeOnExecutor(executorService);
}
 
源代码2 项目: react-native-tcp-socket   文件: TcpSocketModule.java
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("unused")
@ReactMethod
public void end(final Integer cId) {
    new GuardedAsyncTask<Void, Void>(mReactContext.getExceptionHandler()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            TcpSocketClient socketClient = socketClients.get(cId);
            if (socketClient == null) {
                return;
            }
            socketClient.close();
            socketClients.remove(cId);
        }
    }.executeOnExecutor(executorService);
}
 
源代码3 项目: react-native-tcp-socket   文件: TcpSocketModule.java
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("unused")
@ReactMethod
public void listen(final Integer cId, final ReadableMap options) {
    new GuardedAsyncTask<Void, Void>(mReactContext.getExceptionHandler()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            try {
                TcpSocketServer server = new TcpSocketServer(socketClients, TcpSocketModule.this, cId, options);
                socketClients.put(cId, server);
                int port = options.getInt("port");
                String host = options.getString("host");
                onConnect(cId, host, port);
            } catch (Exception uhe) {
                onError(cId, uhe.getMessage());
            }
        }
    }.executeOnExecutor(executorService);
}
 
源代码4 项目: react-native-GPay   文件: AsyncStorageModule.java
/**
 * Clears the database.
 */
@ReactMethod
public void clear(final Callback callback) {
  new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
    @Override
    protected void doInBackgroundGuarded(Void... params) {
      if (!mReactDatabaseSupplier.ensureDatabase()) {
        callback.invoke(AsyncStorageErrorUtil.getDBError(null));
        return;
      }
      try {
        mReactDatabaseSupplier.clear();
        callback.invoke();
      } catch (Exception e) {
        FLog.w(ReactConstants.TAG, e.getMessage(), e);
        callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()));
      }
    }
  }.executeOnExecutor(executor);
}
 
源代码5 项目: react-native-GPay   文件: ImageLoaderModule.java
@ReactMethod
public void queryCache(final ReadableArray uris, final Promise promise) {
  // perform cache interrogation in async task as disk cache checks are expensive
  new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
    @Override
    protected void doInBackgroundGuarded(Void... params) {
      WritableMap result = Arguments.createMap();
      ImagePipeline imagePipeline = Fresco.getImagePipeline();
      for (int i = 0; i < uris.size(); i++) {
        String uriString = uris.getString(i);
        final Uri uri = Uri.parse(uriString);
        if (imagePipeline.isInBitmapMemoryCache(uri)) {
          result.putString(uriString, "memory");
        } else if (imagePipeline.isInDiskCacheSync(uri)) {
          result.putString(uriString, "disk");
        }
      }
      promise.resolve(result);
    }
  }.executeOnExecutor(GuardedAsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码6 项目: react-native-sockets   文件: SocketsModule.java
@Override
public void onCatalystInstanceDestroy() {
    try {
        new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
            @Override
            protected void doInBackgroundGuarded(Void... params) {
                if (client != null) {
                    client.disconnect(false);
                }
                if (server != null) {
                    server.close();
                }
            }
        }.execute().get();
    } catch (InterruptedException ioe) {
        Log.e(eTag, "onCatalystInstanceDestroy", ioe);
    } catch (ExecutionException ee) {
        Log.e(eTag, "onCatalystInstanceDestroy", ee);
    }
}
 
源代码7 项目: react-native-speech   文件: speechModule.java
/***
 * This method will expose all the available languages in TTS engine
 *
 * @param callback
 */
@ReactMethod
public void getLocale(final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            try {
                if (tts == null) {
                    init();
                }
                Locale[] locales = Locale.getAvailableLocales();
                WritableArray data = Arguments.createArray();
                for (Locale locale : locales) {
                    int res = tts.isLanguageAvailable(locale);
                    if (res == TextToSpeech.LANG_COUNTRY_AVAILABLE) {
                        data.pushString(locale.getLanguage());
                    }
                }
                callback.invoke(null, data);
            } catch (Exception e) {
                callback.invoke(e.getMessage());
            }
        }
    }.execute();
}
 
源代码8 项目: react-native-speech   文件: speechModule.java
@ReactMethod
public void isSpeaking(final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            try {
                if (tts.isSpeaking()) {
                    callback.invoke(null, true);
                } else {
                    callback.invoke(null, false);
                }
            } catch (Exception e) {
                callback.invoke(e.getMessage());
            }
        }
    }.execute();
}
 
源代码9 项目: react-native-speech   文件: speechModule.java
@ReactMethod
public void shutDown(final Callback callBack) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            if (tts == null) {
                callBack.invoke(true);
            }
            try {
                tts.shutdown();
                callBack.invoke(null, true);
            } catch (Exception e) {
                callBack.invoke(e.getMessage());
            }
        }
    }.execute();
}
 
源代码10 项目: react-native-udp   文件: UdpSockets.java
@Override
public void onCatalystInstanceDestroy() {
    mShuttingDown = true;

    // serialize on the AsyncTask thread, and block
    try {
        new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
            @Override
            protected void doInBackgroundGuarded(Void... params) {
                for (int i = 0; i < mClients.size(); i++) {
                    try {
                        mClients.valueAt(i).close();
                    } catch (IOException e) {
                        FLog.e(TAG, "exception when shutting down", e);
                    }
                }
                mClients.clear();
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get();
    } catch (InterruptedException ioe) {
        FLog.e(TAG, "onCatalystInstanceDestroy", ioe);
    } catch (ExecutionException ee) {
        FLog.e(TAG, "onCatalystInstanceDestroy", ee);
    }
}
 
源代码11 项目: react-native-udp   文件: UdpSockets.java
/**
 * Leaves a multi-cast group
 */
@ReactMethod
public void dropMembership(final Integer cId, final String multicastAddress) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            UdpSocketClient client = findClient(cId, null);
            if (client == null) {
                return;
            }

            try {
                client.dropMembership(multicastAddress);
            } catch (IOException ioe) {
                // an exception occurred
                FLog.e(TAG, "dropMembership", ioe);
            } finally {
                if (mMulticastLock != null && mMulticastLock.isHeld()) {
                    mMulticastLock.release();
                }
            }
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码12 项目: react-native-udp   文件: UdpSockets.java
/**
 * Sends udp data via the {@link UdpSocketClient}
 */
@ReactMethod
public void send(final Integer cId, final String base64String,
                 final Integer port, final String address, final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            UdpSocketClient client = findClient(cId, callback);
            if (client == null) {
                return;
            }

            try {
                client.send(base64String, port, address, callback);
            } catch (IllegalStateException ise) {
                callback.invoke(UdpErrorUtil.getError(null, ise.getMessage()));
            }catch (UnknownHostException uhe) {
                callback.invoke(UdpErrorUtil.getError(null, uhe.getMessage()));
            } catch (IOException ioe) {
                // an exception occurred
                callback.invoke(UdpErrorUtil.getError(null, ioe.getMessage()));
            }
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码13 项目: react-native-udp   文件: UdpSockets.java
/**
 * Sets the broadcast flag for a given client.
 */
@ReactMethod
public void setBroadcast(final Integer cId, final Boolean flag, final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            UdpSocketClient client = findClient(cId, callback);
            if (client == null) {
                return;
            }

            try {
                client.setBroadcast(flag);
                callback.invoke();
            } catch (SocketException e) {
                callback.invoke(UdpErrorUtil.getError(null, e.getMessage()));
            }
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码14 项目: react-native-android-sqlite   文件: DBManager.java
@ReactMethod
public void query(final String sql, final ReadableArray values, final Callback callback) {
	new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
		@Override
		protected void doInBackgroundGuarded(Void ...params) {
			WritableArray data = Arguments.createArray();

			// FLog.w(ReactConstants.TAG, "dbmanager.query.sql=%s", sql);
			// FLog.w(ReactConstants.TAG, "dbmanager.query.values.size()=%d", values.size());

			try {
				data = mDb.query(sql, values);
			} catch(Exception e) {
				FLog.w(ReactConstants.TAG, "Exception in database query: ", e);
				callback.invoke(ErrorUtil.getError(null, e.getMessage()), null);
			}

			callback.invoke(null, data);
		}
	}.execute();
}
 
源代码15 项目: react-native-android-sqlite   文件: DBManager.java
@ReactMethod
public void exec(final String sql, final ReadableArray values, final Callback callback) {
	new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
		@Override
		protected void doInBackgroundGuarded(Void ...params) {
			try {
				mDb.exec(sql, values);
			} catch(Exception e) {
				FLog.w(ReactConstants.TAG, "Exception in database exec: ", e);
				callback.invoke(ErrorUtil.getError(null, e.getMessage()), null);
			}

			callback.invoke();
		}
	}.execute();
}
 
源代码16 项目: react-native-android-sqlite   文件: DBManager.java
@ReactMethod
public void close(final Callback callback) {
	new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
		@Override
		protected void doInBackgroundGuarded(Void ...params) {
			try {
				mDb.close();
			} catch(Exception e) {
				FLog.w(ReactConstants.TAG, "Exception in database close: ", e);
				callback.invoke(ErrorUtil.getError(null, e.getMessage()), null);
			}

			callback.invoke();
		}
	}.execute();
}
 
源代码17 项目: react-native-tcp-socket   文件: TcpSocketModule.java
/**
 * Creates a TCP Socket and establish a connection with the given host
 *
 * @param cId     socket ID
 * @param host    socket IP address
 * @param port    socket port to be bound
 * @param options extra options
 */
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("unused")
@ReactMethod
public void connect(@NonNull final Integer cId, @NonNull final String host, @NonNull final Integer port, @NonNull final ReadableMap options) {
    new GuardedAsyncTask<Void, Void>(mReactContext.getExceptionHandler()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            TcpSocketClient client = socketClients.get(cId);
            if (client != null) {
                onError(cId, TAG + "createSocket called twice with the same id.");
                return;
            }
            try {
                // Get the network interface
                final String localAddress = options.hasKey("localAddress") ? options.getString("localAddress") : null;
                final String iface = options.hasKey("interface") ? options.getString("interface") : null;
                selectNetwork(iface, localAddress);
                client = new TcpSocketClient(TcpSocketModule.this, cId, null);
                socketClients.put(cId, client);
                client.connect(mReactContext, host, port, options, currentNetwork.getNetwork());
                onConnect(cId, host, port);
            } catch (Exception e) {
                onError(cId, e.getMessage());
            }
        }
    }.executeOnExecutor(executorService);
}
 
private void runInBackground(final Runnable runnable) {
  new GuardedAsyncTask<Void, Void>(mContext) {
    @Override
    protected void doInBackgroundGuarded(Void... params) {
      runnable.run();
    }
  }.execute();
}
 
源代码19 项目: react-native-GPay   文件: NetworkingModule.java
private void cancelRequest(final int requestId) {
  // We have to use AsyncTask since this might trigger a NetworkOnMainThreadException, this is an
  // open issue on OkHttp: https://github.com/square/okhttp/issues/869
  new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
    @Override
    protected void doInBackgroundGuarded(Void... params) {
      OkHttpCallUtil.cancelTag(mClient, Integer.valueOf(requestId));
    }
  }.execute();
}
 
源代码20 项目: react-native-GPay   文件: AsyncStorageModule.java
/**
 * Returns an array with all keys from the database.
 */
@ReactMethod
public void getAllKeys(final Callback callback) {
  new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
    @Override
    protected void doInBackgroundGuarded(Void... params) {
      if (!ensureDatabase()) {
        callback.invoke(AsyncStorageErrorUtil.getDBError(null), null);
        return;
      }
      WritableArray data = Arguments.createArray();
      String[] columns = {KEY_COLUMN};
      Cursor cursor = mReactDatabaseSupplier.get()
          .query(TABLE_CATALYST, columns, null, null, null, null, null);
      try {
        if (cursor.moveToFirst()) {
          do {
            data.pushString(cursor.getString(0));
          } while (cursor.moveToNext());
        }
      } catch (Exception e) {
        FLog.w(ReactConstants.TAG, e.getMessage(), e);
        callback.invoke(AsyncStorageErrorUtil.getError(null, e.getMessage()), null);
        return;
      } finally {
        cursor.close();
      }
      callback.invoke(null, data);
    }
  }.executeOnExecutor(executor);
}
 
源代码21 项目: react-native-lanscan   文件: LANScanModule.java
@ReactMethod
public void stop() {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            ((ThreadPoolExecutor)ManagedThreadPoolExecutor.THREAD_POOL_EXECUTOR_PINGS).shutdownNow();
            ((ThreadPoolExecutor)ManagedThreadPoolExecutor.THREAD_POOL_EXECUTOR_BROADCAST).shutdownNow();

            long startTime = System.currentTimeMillis();
            long endTime = 0L;
            long timeout = 1000;
            boolean isTerminated_broadcast = false;
            boolean isTerminated_pings = false;

            // wait until all the threads are terminated
            // or grace timeout finishes
            while(!isTerminated_broadcast || !isTerminated_pings || endTime < timeout) {
                isTerminated_broadcast = ((ThreadPoolExecutor)ManagedThreadPoolExecutor.THREAD_POOL_EXECUTOR_BROADCAST).isTerminated();
                isTerminated_pings = ((ThreadPoolExecutor)ManagedThreadPoolExecutor.THREAD_POOL_EXECUTOR_BROADCAST).isTerminated();
                endTime = (new Date()).getTime() - startTime;
            }

            // successfully stopped the tasks... send top event
            sendEvent(getReactApplicationContext(), EVENT_STOP, null);
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码22 项目: react-native-speech   文件: speechModule.java
@ReactMethod
public void stop() {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            tts.stop();
        }
    }.execute();
}
 
源代码23 项目: react-native-udp   文件: UdpSockets.java
/**
 * Binds to a given port and address, and begins listening for data.
 */
@ReactMethod
public void bind(final Integer cId, final Integer port, final @Nullable String address,
                 final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            UdpSocketClient client = findClient(cId, callback);
            if (client == null) {
                    return;
            }

            try {
                client.bind(port, address);

                WritableMap result = Arguments.createMap();
                result.putString("address", address);
                result.putInt("port", port);

                callback.invoke(null, result);
            } catch (SocketException se) {
                // Socket is already bound or a problem occurred during binding
                callback.invoke(UdpErrorUtil.getError(null, se.getMessage()));
            } catch (IllegalArgumentException iae) {
                // SocketAddress is not supported
                callback.invoke(UdpErrorUtil.getError(null, iae.getMessage()));
            } catch (IOException ioe) {
                // an exception occurred
                callback.invoke(UdpErrorUtil.getError(null, ioe.getMessage()));
            }
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码24 项目: react-native-udp   文件: UdpSockets.java
/**
 * Closes a specific client's socket, and removes it from the list of known clients.
 */
@ReactMethod
public void close(final Integer cId, final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            UdpSocketClient client = findClient(cId, callback);
            if (client == null) {
                return;
            }

            if (mMulticastLock != null && mMulticastLock.isHeld() && client.isMulticast()) {
                // drop the multi-cast lock if this is a multi-cast client
                mMulticastLock.release();
            }

            try {
                client.close();
                callback.invoke();
            } catch (IOException ioe) {
                callback.invoke(UdpErrorUtil.getError(null, ioe.getMessage()));
            }

            mClients.remove(cId);
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码25 项目: react-native-udp   文件: UdpSockets.java
/**
 * Notifies the javascript layer upon data receipt.
 */
@Override
public void didReceiveData(final UdpSocketClient socket, final String data, final String host, final int port) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            int clientID = -1;
            for(int i = 0; i < mClients.size(); i++) {
                clientID = mClients.keyAt(i);
                // get the object by the key.
                if (socket.equals(mClients.get(clientID))) {
                    break;
                }
            }

            if (clientID == -1) {
                return;
            }

            WritableMap eventParams = Arguments.createMap();
            eventParams.putString("data", data);
            eventParams.putString("address", host);
            eventParams.putInt("port", port);

            ReactContext reactContext = UdpSockets.this.getReactApplicationContext();
            reactContext
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit("udp-" + clientID + "-data", eventParams);
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
源代码26 项目: react-native-android-sqlite   文件: DBManager.java
@ReactMethod
public void init(final String name, final Callback callback) {
	new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
		@Override
		protected void doInBackgroundGuarded(Void ...params) {
			// FLog.w(ReactConstants.TAG, "dbmanager.init.name=%s", name);
			mDb = new SQLiteManager(getReactApplicationContext(), name);
			mDb.init();
			callback.invoke();
		}
	}.execute();
}
 
源代码27 项目: react-native-speech   文件: speechModule.java
@ReactMethod
public void speak(final ReadableMap args, final Callback callback) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            if (tts == null) {
                init();
            }
            String text = args.hasKey("text") ? args.getString("text") : null;
            String language = args.hasKey("language") ? args.getString("language") : null;
            Boolean forceStop = args.hasKey("forceStop") ? args.getBoolean("forceStop") : null;
            Float pitch = args.hasKey("pitch") ? (float) args.getDouble("pitch") : null;
            if (tts.isSpeaking()) {
                //Force to stop and start new speech
                if (forceStop != null && forceStop) {
                    tts.stop();
                } else {
                    callback.invoke("TTS is already speaking something , Please shutdown or stop  TTS and try again");
                    return;
                }
            }
            if (args.getString("text") == null || text == "") {
                callback.invoke("t can not be blank");
                return;
            }
            try {
                if (language != null && language != "") {
                    tts.setLanguage(new Locale(language));
                } else {
                    //Setting up default language
                    tts.setLanguage(new Locale("en"));
                }
                //Set the pitch if provided by the user
                if (pitch != null) {
                    tts.setPitch(pitch);
                }
                //TODO:: Need to implement the UTTERANCE Id and give the callback
                int speakResult = 0;
                if (Build.VERSION.SDK_INT >= 21)
                    speakResult = tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
                else
                    speakResult = tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);

                if (speakResult < 0)
                    throw new Exception("Speak failed, make sure that TTS service is installed on you device");

                callback.invoke(null, true);
            } catch (Exception e) {
                callback.invoke(e.getMessage());
            }
        }
    }.execute();
}
 
源代码28 项目: react-native-udp   文件: UdpSockets.java
/**
 * Joins a multi-cast group
 */
@ReactMethod
public void addMembership(final Integer cId, final String multicastAddress) {
    new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
        @Override
        protected void doInBackgroundGuarded(Void... params) {
            UdpSocketClient client = findClient(cId, null);
            if (client == null) {
                return;
            }

            if (mMulticastLock == null) {
                WifiManager wifiMgr = (WifiManager) getReactApplicationContext()
                    .getApplicationContext()
                    .getSystemService(Context.WIFI_SERVICE);
                mMulticastLock = wifiMgr.createMulticastLock("react-native-udp");
                mMulticastLock.setReferenceCounted(true);
            }

           try {
                mMulticastLock.acquire();
                client.addMembership(multicastAddress);
            } catch (IllegalStateException ise) {
                // an exception occurred
                if (mMulticastLock != null && mMulticastLock.isHeld()) {
                    mMulticastLock.release();
                }
                FLog.e(TAG, "addMembership", ise);
            } catch (UnknownHostException uhe) {
                // an exception occurred
                if (mMulticastLock != null && mMulticastLock.isHeld()) {
                    mMulticastLock.release();
                }
                FLog.e(TAG, "addMembership", uhe);
            } catch (IOException ioe) {
                // an exception occurred
                if (mMulticastLock != null && mMulticastLock.isHeld()) {
                    mMulticastLock.release();
                }
                FLog.e(TAG, "addMembership", ioe);
            }
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
 
 同包方法