runOnUiThread не выполняется - PullRequest
       54

runOnUiThread не выполняется

0 голосов
/ 30 сентября 2018

Я пытаюсь запустить этот код, но код внутри моего потока 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

1 Ответ

0 голосов
/ 01 октября 2018

Toast нужно context, и когда вы создаете экземпляр класса Activity с помощью new, вы просто создаете класс 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: сначала создайте класс, расширяющий класс приложения:

public class Myapp extends Application{
public PubSubActivityTemp pubSubActivityTemp;

}

в файле AndroidManifast.xml в теге <application>, используйте этот класс для атрибута 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

...