我正在尝试运行此代码,但runOnUi线程内的代码未执行。我正在使用evernote-android-job。
他是定期运行的代码:
public class TempJob extends Job {
public static final String TAG = "job_temp_mqtt";
@Override
@NonNull
protected Result onRunJob(@NonNull Params params) {
Log.d("I'm here", "Position 0");
Looper.prepare();
PubSubActivityTemp worker = new PubSubActivityTemp();
Log.d("I'm here", "Position 1");
worker.exe();
return Result.SUCCESS;
}
public static void scheduleJob() {
Set<JobRequest> jobRequests =
JobManager.instance().getAllJobRequestsForTag(TempJob.TAG);
if (!jobRequests.isEmpty()) {
Log.d("Check: ", "Job is not Empty");
// return;
}
new JobRequest.Builder(TempJob.TAG)
.setPeriodic(TimeUnit.MINUTES.toMillis(15),
TimeUnit.MINUTES.toMillis(7))
.setUpdateCurrent(true) // calls
cancelAllForTag(NoteSyncJob.TAG) for you
.setRequiredNetworkType(JobRequest.NetworkType.ANY)
.setRequirementsEnforced(true)
.build()
.schedule();
}
}
这是活动中的代码:
public class PubSubActivityTemp extends Activity {
static final String LOG_TAG = GraphSelectType.class.getCanonicalName();
// --- Constants to modify per your configuration ---
// IoT endpoint
// AWS Iot CLI describe-endpoint call returns: XXXXXXXXXX.iot.
<region>.amazonaws.com
private static final String CUSTOMER_SPECIFIC_ENDPOINT = "*************-
ats.iot.us-east-1.amazonaws.com";
// Cognito pool ID. For this app, pool needs to be unauthenticated pool
with
// AWS IoT permissions.
private static final String COGNITO_POOL_ID = "us-east-
1:*************-75c2-4258-b663-21*********83e";
// Name of the AWS IoT policy to attach to a newly created certificate
private static final String AWS_IOT_POLICY_NAME = "PubSub******Cert";
// Region of AWS IoT
private static final Regions MY_REGION = Regions.US_EAST_1;
// Filename of KeyStore file on the filesystem
private static final String KEYSTORE_NAME = "iot_keystore";
// Password for the private key in the KeyStore
private static final String KEYSTORE_PASSWORD = "password";
// Certificate and key aliases in the KeyStore
private static final String CERTIFICATE_ID = "default";
TextView tvStatus;
// TextView tvLastMessage;
Handler mHandler;
AWSIotClient mIotAndroidClient;
AWSIotMqttManager mqttManager;
String clientId;
String keystorePath;
String keystoreName;
String keystorePassword;
KeyStore clientKeyStore = null;
String certificateId;
CognitoCachingCredentialsProvider credentialsProvider;
int tracker = 0; //0 is on, 1 is off
private String topic = "Simran*****";
private String msg0 = "on";
private String msg1 = "off";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void exe() {
Log.d("I'm here", "Position 2");
new Thread() {
public void run() {
Log.d("I'm here", "Position 3");
runOnUiThread(() -> {
Log.d("I'm here", "Position 4");
Toast.makeText(PubSubActivityTemp.this, "Storage not
available", Toast.LENGTH_SHORT).show();
});
Log.d("I'm here", "Position 5");
}
}.start();
}
public void mqtt() {
// tvStatus = (TextView) findViewById(R.id.tvStatus);
// tvLastMessage = (TextView) findViewById(R.id.tvLastMessage);
// MQTT client IDs are required to be unique per AWS IoT account.
// This UUID is "practically unique" but does not _guarantee_
// uniqueness.
clientId = UUID.randomUUID().toString();
// Initialize the AWS Cognito credentials provider
credentialsProvider = new CognitoCachingCredentialsProvider(
// getApplicationContext(), // context
TempApplication.getAppContext(),
COGNITO_POOL_ID, // Identity Pool ID
MY_REGION // Region
);
Region region = Region.getRegion(MY_REGION);
// MQTT Client
mqttManager = new AWSIotMqttManager(clientId,
CUSTOMER_SPECIFIC_ENDPOINT);
// Set keepalive to 10 seconds. Will recognize disconnects more
quickly but will also send
// MQTT pings every 10 seconds.
mqttManager.setKeepAlive(10);
// Set Last Will and Testament for MQTT. On an unclean disconnect
(loss of connection)
// AWS IoT will publish this message to alert other clients.
AWSIotMqttLastWillAndTestament lwt = new
AWSIotMqttLastWillAndTestament("my/lwt/topic",
"Android client lost connection", AWSIotMqttQos.QOS0);
mqttManager.setMqttLastWillAndTestament(lwt);
// IoT Client (for creation of certificate if needed)
mIotAndroidClient = new AWSIotClient(credentialsProvider);
mIotAndroidClient.setRegion(region);
keystorePath = getFilesDir().getPath();
keystoreName = KEYSTORE_NAME;
keystorePassword = KEYSTORE_PASSWORD;
certificateId = CERTIFICATE_ID;
// To load cert/key from keystore on filesystem
try {
if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath,
keystoreName)) {
if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId,
keystorePath,
keystoreName, keystorePassword)) {
Log.i(LOG_TAG, "Certificate " + certificateId
+ " found in keystore - using for MQTT.");
// load keystore from file into memory to pass on
connection
clientKeyStore =
AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// btnConnect.setEnabled(true);
} else {
Log.i(LOG_TAG, "Key/cert " + certificateId + " not found
in keystore.");
}
} else {
Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName
+ " not found.");
}
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred retrieving cert/key from
keystore.", e);
}
if (clientKeyStore == null) {
Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new
key and certificate.");
new Thread(new Runnable() {
@Override
public void run() {
try {
// Create a new private key and certificate. This call
// creates both on the server and returns them to the
// device.
CreateKeysAndCertificateRequest
createKeysAndCertificateRequest =
new CreateKeysAndCertificateRequest();
createKeysAndCertificateRequest.setSetAsActive(true);
final CreateKeysAndCertificateResult
createKeysAndCertificateResult;
createKeysAndCertificateResult =
mIotAndroidClient.createKeysAndCertificate
(createKeysAndCertificateRequest);
Log.i(LOG_TAG,
"Cert ID: " +
createKeysAndCertificateResult.getCertificateId() +
" created.");
// store in keystore for use in MQTT client
// saved as alias "default" so a new certificate isn't
// generated each run of this application
AWSIotKeystoreHelper.saveCertificateAndPrivateKey
(certificateId,
createKeysAndCertificateResult.getCertificatePem(),
createKeysAndCertificateResult.getKeyPair().getPrivateKey(),
keystorePath, keystoreName, keystorePassword);
// load keystore from file into memory to pass on
// connection
clientKeyStore =
AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// Attach a policy to the newly created certificate.
// This flow assumes the policy was already created in
// AWS IoT and we are now just attaching it to the
// certificate.
AttachPrincipalPolicyRequest policyAttachRequest =
new AttachPrincipalPolicyRequest();
policyAttachRequest.setPolicyName(AWS_IOT_POLICY_NAME);
policyAttachRequest.setPrincipal(createKeysAndCertificateResult
.getCertificateArn());
mIotAndroidClient.attachPrincipalPolicy(policyAttachRequest);
runOnUiThread(new Runnable() {
@Override
public void run() {
// btnConnect.setEnabled(true);
}
});
} catch (Exception e) {
Log.e(LOG_TAG,
"Exception occurred when generating new
private key and certificate.",
e);
}
}
}).start();
}
connect();
subscribe();
}
public void connect() {
try {
mqttManager.connect(clientKeyStore, new
AWSIotMqttClientStatusCallback() {
@Override
public void onStatusChanged(final AWSIotMqttClientStatus
status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status));
runOnUiThread(new Runnable() {
@Override
public void run() {
if (status == AWSIotMqttClientStatus.Connecting) {
tvStatus.setText("Connecting...");
} else if (status ==
AWSIotMqttClientStatus.Connected) {
tvStatus.setText("Connected");
} else if (status ==
AWSIotMqttClientStatus.Reconnecting) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.",
throwable);
}
tvStatus.setText("Reconnecting");
} else if (status ==
AWSIotMqttClientStatus.ConnectionLost) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.",
throwable);
}
tvStatus.setText("Disconnected");
} else {
tvStatus.setText("Disconnected");
}
}
});
}
});
} catch (final Exception e) {
Log.e(LOG_TAG, "Connection error.", e);
tvStatus.setText("Error! " + e.getMessage());
}
}
public void subscribe() {
try {
mqttManager.subscribeToTopic(topic, AWSIotMqttQos.QOS0,
new AWSIotMqttNewMessageCallback() {
@Override
public void onMessageArrived(final String topic, final
byte[] data) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
String message = new String(data,
"UTF-8");
Log.d(LOG_TAG, "Message arrived:");
Log.d(LOG_TAG, " Topic: " + topic);
Log.d(LOG_TAG, " Message: " +
message);
//
tvLastMessage.setText(message);
} catch (UnsupportedEncodingException e) {
Log.e(LOG_TAG, "Message encoding
error.", e);
}
}
});
}
});
} catch (Exception e) {
Log.e(LOG_TAG, "Subscription error.", e);
}
}
}
这是logcat的输出。我只过滤掉必要的输出。我没有收到任何警告或错误:
09-30 11:55:23.662 5705-6268/com.simran.powermanagement D/I'm here:
Position 0
09-30 11:55:23.663 5705-6268/com.simran.powermanagement D/I'm here:
Position 1
Position 2
09-30 11:55:23.665 5705-6269/com.simran.powermanagement D/I'm here:
Position 3
09-30 11:55:23.665 5705-6269/com.simran.powermanagement D/I'm here:
Position 5
答案 0 :(得分:0)
Toast
需要context
,当您使用new
实例化Activity类时,您只需创建一个没有上下文的Java类。如果您需要某种活动方法,则必须发送您的活动或其Job
类的上下文对象,并将其用于创建活动。像这样:
public class PubSubActivityTemp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
yourJob job=new yourJob (this);
}
}
在您的工作类别中:
public class TempJob extends Job {
Activity activity;
public TempJob (Activity activity){
this.activity=activity;
PubSubActivityTemp worker=(PubSubActivityTemp)activity;
}
}
如果您不想在PubSubActivityTemp
中创建工作,我建议您使用这种方式实例化PubSubActivityTemp
:
首先创建一个扩展Application类的类:
public class Myapp extends Application{
public PubSubActivityTemp pubSubActivityTemp;
}
在<application>
标签中的AndroidManifast.xml文件中,此类用于name
属性:
<application name=".Myapp ">
在您的PubSubActivityTemp
onCreate()
方法中:
public class PubSubActivityTemp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp myApp=(MyApp) getApplicationContext();// or getApplication();
myApp.pubSubActivityTemp=this;
}
}
在每个需要进行PubSubActivityTemp
的活动中,只需将getApplicationContext
和其中的内容发送给Context
即可:
public class TempJob extends Job {
Activity activity;// or use Context context;
public TempJob (Activity activity){
this.activity=activity;
MyApp myApp=(MyApp)activity.getApplicationContext();
PubSubActivityTemp worker=myApp.pubSubActivityTemp;
}
}
在另一个需要工作的课程中:
public class AnotherActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TempJob job=new TempJob(this);
}
}
,如果您只想查找一些代码,可以使用Log.v()
而不是Toast