Empower growth and innovation with the latest Front-end Dev insights

In 2026, why does a Uni-app Android app ask me to log in again after I kill and reopen the process, while the WeChat Mini Program still recognizes me—aren't the caches on both sides the same place?

Oct 26, 2026 Read: 23

Bottom line first: When a Uni-app Android app requires re-login after the process is killed and reopened, while the WeChat Mini Program still naturally recognizes you, in most cases this is not because uni.setStorage failed to write. It is because the storage containers, startup restoration order, and token invalidation policies on the two ends are not aligned—Mini Program cache is hosted by the WeChat client, while App data goes to native storage, so they are two different sets of data from the start. Based on 2026 project delivery experience, first align three things—the same key name, the same serialization, and the same restoration entry—and then decide whether to add a wrapper layer or change renewal. This is usually less rework than asking users to log in again.

The Mini Program still recognizes me, but the App cold start acts like the first launch—where is the difference?

The difference comes down to two things: who manages this cache, and when it gets cleared. The Mini Program runs inside the WeChat container, and its cache is hosted by the WeChat client; if the user does not actively clear it or log out, the data often stays for a long time. The App lands in the system's native storage and is affected by system storage management, user cache clearing, and cleaning apps' cleanup policies. After the process is killed, whether the data can be read back depends on whether the write path and restoration entry are centralized. The same uni.setStorage statement does not point to the same underlying data on different ends, so an observation like 'it is still there in the developer tools' is hard to carry directly over to a real-device cold start.

There is another more hidden difference: a hot start is not the same as a cold start. When testing with hot reload or by switching to the background and back, in-memory state is still there and everything looks normal; only actually killing the process and reopening it exposes problems in the restoration order. In 2026 multi-platform projects, it is worth writing one item explicitly into the acceptance criteria: perform at least one process-kill cold-start verification on a real Android device.

  • Misjudgment 1: verified only in H5 or the Mini Program, not in an App real-device cold start.
  • Misjudgment 2: the login page's onLoad writes an empty user object first, overwriting the existing login state.
  • Misjudgment 3: the token is stored but user info is not, while the startup condition checks user info.
  • Misjudgment 4: the page uses an in-memory variable as the 'logged in' flag, which is bound to be lost on cold start.

Before changing storage, first tell whether it was not saved or not restored

For troubleshooting order, start with 'can it be read?' rather than 'was it written?'. In App.vue's onLaunch, log the return value and type of getStorageSync once, then compare them with the key name and data structure at the write location. In most cases you can determine the direction within ten minutes and avoid repeatedly changing code in the wrong place.

  1. Record the return value: read token and user info in onLaunch and note whether the return is an empty string, null, or an object with the wrong structure.
  2. Check the key name: check whether the key was changed at the write location, or whether one side stores an object while the other stores a JSON.stringify string.
  3. Check overwrites: confirm whether a default value is written during startup, or whether logout logic is triggered by mistake.
  4. Retest on a real device: verify with a cold start after killing the process; do not use hot reload as a substitute for cold start.

The pass criterion for this step is plain: for the same login data, the field names and types read on Mini Program, App, and H5 are consistent. If this cannot be achieved, all later invalidation handling degenerates into patching.

Check storage, restoration, and invalidation in three separate layers—do not investigate them all mixed together

Split the problem into three layers because their acceptance criteria differ: the storage layer checks whether key names and types are consistent; the restoration layer checks whether the startup order causes overwrites; the invalidation layer checks whether a 401 leads to only one login redirect. If the three layers are investigated together, it is easy to fall into the loop of 'changed storage but it still gets lost'.

  1. Storage layer: unify the key prefix and serialization method; immediately read once after writing for self-check; the pass criterion is consistent types read on all three ends.
  2. Restoration layer: restore only once in onLaunch; the login page does not write default empty values; the pass criterion is that the token is available on the first screen after cold start.
  3. Invalidation layer: intercept 401 uniformly; allow only one request to refresh the token at a time; the pass criterion is that concurrent 401s trigger only one redirect to the login page.

An example from delivery: In 2026, a project required the Mini Program and Android App to enter testing together within two weeks, but the API provider had not yet provided a field for refreshing the token, and the login page wrote a default empty user object in onLoad. There were not many choices at the time. The approach was to first collect keys into constants with prefixes, perform restoration only once in App.vue's onLaunch, remove the default write from the login page, and add a fallback in the request wrapper for 401 (clear the token and redirect to the login page once). As a result, feedback about losing login state on cold start basically disappeared. There was also a cost—the first version missed that nvue pages use a different read path, and after testing there was about half a day to one day of rework (experience range, depending on the number of pages); concurrent 401s still redirected to login twice and could only be addressed in the next iteration by adding a request queue. Such rework is often not technically difficult; it is because restoration entries are too scattered.

  • Using an in-memory variable as the 'logged in' flag will definitely be lost on cold start.
  • Restoring repeatedly in every page's onShow causes states to overwrite each other.
  • Token refresh has no queue, so multiple 401s kick the user out at the same time.
  • Treating 'not logged in' and 'token expired' as the same redirect, with the prompt text also mixed together.

Reading storage directly, adding a persistence wrapper, and backend renewal—who is each approach suitable for?

None of the three approaches is absolutely better or worse; the key is team size and the complexity of login state. A relatively common path in 2026 is to first use a lightweight wrapper to consolidate read/write entries, then decide based on token lifetime whether to add backend renewal, avoiding a heavy architecture from the start.

  • Read storage directly: small change, commonly within 0.5 person-days; suitable for campaign-type projects with few pages and long token lifetime; the risk is that invalidation checks are scattered across pages, and later requirements are easy to miss.
  • Add a persistence wrapper: typical range about 1 to 2 person-days; suitable for projects shared across multiple ends that need unified keys and restoration entries; the risk is over-wrapping, making simple projects take an extra loop.
  • Backend renewal plus unified frontend interception: integration cycle commonly 2 to 5 days (experience range, depending on API readiness); suitable for businesses with short-lived tokens and many concurrent requests; the risk is that when APIs are not ready, the frontend can only use placeholders first.

Whether it is done well is not judged by how many wrapper layers there are, but by three retestable results: whether the first screen after cold start carries login state, whether concurrent 401s trigger only one login redirect, and whether logout clears data on the relevant ends. Only when all three can be retested and pass is it considered closed.

When is it worth doing this, and when should you not?

Suitable scenarios: multiple ends launch at the same time, cold-start login-state restoration is needed, the token has a clear lifetime, and the team already has a unified request wrapper. For such projects, consolidating keys, serialization, and restoration entries usually brings more benefit than cost.

Not applicable or requiring caution: one-off campaign pages, purely display-oriented H5, and internal admin tools where login state only exists in the current session and users can accept logging in again—adding a full persistence layer to such projects may cost more to maintain than it returns. In addition, businesses with higher security requirements should not rely only on frontend storage for sensitive information; this needs separate verification against platform rules and backend solutions. The boundary can be noted separately: login-state problems should be layered first, then decide whether to wrap; not every 'login drop' should be counted as cache not being saved.

Frequently asked questions

In Uni-app, uni.setStorageSync stored the token, but the App reads an empty string after cold start—which step should I check first?

First check whether the key used for writing and reading is exactly the same, and whether an object or a string was stored. Then check whether a default value before onLaunch overwrote the existing login state. Finally, kill the process on a real device and retest once.

The Mini Program can read the cache—why can't the App read the same one?

The two ends are not the same storage container: Mini Program cache is hosted by the WeChat client, while the App stores data in native storage. If key names and serialization methods are not unified, the App may read empty values. Read and write within the same wrapper.

If login state is lost, is it simpler to just make the user log in again?

It is simpler in the short term, but it mixes cold-start failure, token expiration, and concurrent 401s into the same experience. It is better to at least distinguish 'not logged in' from 'expired', and handle redirect locations and prompt copy separately.

Should the App store the token in plus.storage instead of using the uni API?

For the business layer, using the uni API is usually enough. Evaluate plus storage only when there is a real need to read from nvue or the native layer, but synchronize cleanup policies to avoid inconsistency between the two data copies.

Should login-state restoration be done once in App.vue, or checked in every page's onShow?

Centralizing it once is more stable. Repeated restoration on every page easily causes states to overwrite each other; pages only need a lightweight check like 'if there is no login state, redirect to the login page'.


Next step suggestion: First add a read log in App.vue's onLaunch to confirm whether the token is actually there during cold start; then collect key, serialization, and 401 redirects into the same request wrapper file. This approach is suitable for projects that share login state across multiple ends, and not suitable for one-off pages that can accept re-login every time; when sensitive information is involved, verify separately against platform rules and backend solutions.

Have a similar project in mind?
Contact us for a one-to-one project reference proposal
Obtain Proposal
Interested in this topic?
10-year tech team — reference proposal within 24 hours
Obtain Proposal
Are you ready?
Then reach out to us!
+86-13370032918
Discover more services, feel free to contact us anytime.
Please fill in your requirements
What services would you like us to provide for you?
Your Budget
ct.
Our WeChat
Professional technical solutions
Phone
+86-13370032918 (Manager Jin)
The phone is busy or unavailable; feel free to add me on WeChat.
E-mail
349077570@qq.com
Submitted successfully
Thank you for your trust. We will contact you soon!
Recommended projects for you